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

Skip to content

Commit 4dea559

Browse files
authored
Merge pull request #1038 from utPLSQL/bugfix/throws_exceptions_list_parsing
Moved validation of `--%throws` annotation values.
2 parents 33f5152 + 8e43a08 commit 4dea559

13 files changed

Lines changed: 390 additions & 388 deletions

source/core/types/ut_executable_test.tpb

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ create or replace type body ut_executable_test as
3131

3232
member procedure do_execute(
3333
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
34-
a_expected_error_codes in ut_integer_list
34+
a_expected_error_codes in ut_varchar2_rows
3535
) is
3636
l_completed_without_errors boolean;
3737
begin
@@ -40,10 +40,114 @@ create or replace type body ut_executable_test as
4040

4141
member function do_execute(
4242
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
43-
a_expected_error_codes in ut_integer_list
43+
a_expected_error_codes in ut_varchar2_rows
4444
) return boolean is
4545
l_expected_except_message varchar2(4000);
46+
l_expected_error_numbers ut_integer_list;
4647

48+
function build_exception_numbers_list(
49+
a_item in out nocopy ut_suite_item,
50+
a_expected_error_codes in ut_varchar2_rows
51+
) return ut_integer_list is
52+
l_exception_number integer;
53+
l_exception_number_list ut_integer_list := ut_integer_list();
54+
c_regexp_for_exception_no constant varchar2(30) := '^-?[[:digit:]]{1,5}$';
55+
56+
c_integer_exception constant varchar2(1) := 'I';
57+
c_named_exception constant varchar2(1) := 'N';
58+
59+
function is_valid_qualified_name (a_name varchar2) return boolean is
60+
l_name varchar2(500);
61+
begin
62+
l_name := dbms_assert.qualified_sql_name(a_name);
63+
return true;
64+
exception when others then
65+
return false;
66+
end;
67+
68+
function check_exception_type(a_exception_name in varchar2) return varchar2 is
69+
l_exception_type varchar2(50);
70+
begin
71+
--check if it is a predefined exception
72+
begin
73+
execute immediate 'begin null; exception when '||a_exception_name||' then null; end;';
74+
l_exception_type := c_named_exception;
75+
exception
76+
when others then
77+
if dbms_utility.format_error_stack() like '%PLS-00485%' then
78+
declare
79+
e_invalid_number exception;
80+
pragma exception_init ( e_invalid_number, -6502 );
81+
begin
82+
execute immediate 'declare x integer := '||a_exception_name||'; begin null; end;';
83+
l_exception_type := c_integer_exception;
84+
exception
85+
when others then
86+
null;
87+
end;
88+
end if;
89+
end;
90+
return l_exception_type;
91+
end;
92+
93+
function get_exception_number (a_exception_var in varchar2) return integer is
94+
l_exc_no integer;
95+
l_exc_type varchar2(50);
96+
function remap_no_data_found (a_number integer) return integer is
97+
begin
98+
return case a_number when 100 then -1403 else a_number end;
99+
end;
100+
begin
101+
l_exc_type := check_exception_type(a_exception_var);
102+
103+
execute immediate
104+
case l_exc_type
105+
when c_integer_exception then
106+
'declare l_exception number; begin :l_exception := '||a_exception_var||'; end;'
107+
when c_named_exception then
108+
'begin raise '||a_exception_var||'; exception when others then :l_exception := sqlcode; end;'
109+
else
110+
'begin :l_exception := null; end;'
111+
end
112+
using out l_exc_no;
113+
114+
return remap_no_data_found(l_exc_no);
115+
end;
116+
117+
begin
118+
if a_expected_error_codes is not empty then
119+
for i in 1 .. a_expected_error_codes.count loop
120+
/**
121+
* Check if its a valid qualified name and if so try to resolve name to an exception number
122+
*/
123+
if is_valid_qualified_name(a_expected_error_codes(i)) then
124+
l_exception_number := get_exception_number(a_expected_error_codes(i));
125+
elsif regexp_like(a_expected_error_codes(i), c_regexp_for_exception_no) then
126+
l_exception_number := a_expected_error_codes(i);
127+
end if;
128+
129+
if l_exception_number is null then
130+
a_item.put_warning(
131+
'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Parameter ignored.',
132+
self.procedure_name,
133+
a_item.line_no
134+
);
135+
elsif l_exception_number >= 0 then
136+
a_item.put_warning(
137+
'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Exception value must be a negative integer. Parameter ignored.',
138+
self.procedure_name,
139+
a_item.line_no
140+
);
141+
else
142+
l_exception_number_list.extend;
143+
l_exception_number_list(l_exception_number_list.last) := l_exception_number;
144+
end if;
145+
l_exception_number := null;
146+
end loop;
147+
end if;
148+
149+
return l_exception_number_list;
150+
end;
47151
function failed_expec_errnum_message(a_expected_error_codes in ut_integer_list) return varchar is
48152
l_actual_error_no integer;
49153
l_expected_error_codes varchar2(4000);
@@ -72,9 +176,9 @@ create or replace type body ut_executable_test as
72176
begin
73177
--Create a ut_executable object and call do_execute after that get the data to know the test's execution result
74178
self.do_execute(a_item);
75-
76-
if a_expected_error_codes is not null and a_expected_error_codes is not empty then
77-
l_expected_except_message := failed_expec_errnum_message(a_expected_error_codes);
179+
l_expected_error_numbers := build_exception_numbers_list(a_item, a_expected_error_codes);
180+
if l_expected_error_numbers is not null and l_expected_error_numbers is not empty then
181+
l_expected_except_message := failed_expec_errnum_message( l_expected_error_numbers );
78182

79183
if l_expected_except_message is not null then
80184
ut_expectation_processor.add_expectation_result(

source/core/types/ut_executable_test.tps

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ create or replace type ut_executable_test authid current_user under ut_executabl
2222

2323
member procedure do_execute(
2424
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
25-
a_expected_error_codes in ut_integer_list
25+
a_expected_error_codes in ut_varchar2_rows
2626
),
2727

2828
member function do_execute(
2929
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
30-
a_expected_error_codes in ut_integer_list
30+
a_expected_error_codes in ut_varchar2_rows
3131
) return boolean
3232

3333
) final;

source/core/types/ut_suite_cache_row.tps

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ create type ut_suite_cache_row as object (
3333
before_test_list ut_executables,
3434
after_each_list ut_executables,
3535
after_test_list ut_executables,
36-
expected_error_codes ut_integer_list,
36+
expected_error_codes ut_varchar2_rows,
3737
tags ut_varchar2_rows,
3838
item ut_executable_test
3939
)

source/core/types/ut_suite_item.tpb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@ create or replace type body ut_suite_item as
9797
self.results_count.increase_warning_count;
9898
end;
9999

100+
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2, a_procedure_name varchar2, a_line_no integer) is
101+
l_result varchar2(1000);
102+
begin
103+
l_result := self.object_owner || '.' || self.object_name ;
104+
if a_procedure_name is not null then
105+
l_result := l_result || '.' || a_procedure_name ;
106+
end if;
107+
put_warning( a_message || chr( 10 ) || 'at package "' || upper(l_result) || '", line ' || a_line_no );
108+
end;
109+
100110
member function get_transaction_invalidators return ut_varchar2_list is
101111
begin
102112
return transaction_invalidators;

source/core/types/ut_suite_item.tps

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ create or replace type ut_suite_item force under ut_event_item (
8484
not instantiable member procedure mark_as_errored(self in out nocopy ut_suite_item, a_error_stack_trace varchar2),
8585
not instantiable member function get_error_stack_traces return ut_varchar2_list,
8686
not instantiable member function get_serveroutputs return clob,
87-
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2)
87+
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2),
88+
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2, a_procedure_name varchar2, a_line_no integer)
8889
)
8990
not final not instantiable
9091
/

source/core/types/ut_test.tpb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ create or replace type body ut_test as
1818

1919
constructor function ut_test(
2020
self in out nocopy ut_test, a_object_owner varchar2 := null, a_object_name varchar2, a_name varchar2,
21-
a_line_no integer, a_expected_error_codes ut_integer_list := null, a_tags ut_varchar2_rows := null
21+
a_line_no integer, a_expected_error_codes ut_varchar2_rows := null, a_tags ut_varchar2_rows := null
2222
) return self as result is
2323
begin
2424
self.self_type := $$plsql_unit;

source/core/types/ut_test.tps

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ create or replace type ut_test force under ut_suite_item (
5454
/**
5555
*Holds the expected error codes list when the user use the annotation throws
5656
*/
57-
expected_error_codes ut_integer_list,
57+
expected_error_codes ut_varchar2_rows,
5858
constructor function ut_test(
5959
self in out nocopy ut_test, a_object_owner varchar2 := null, a_object_name varchar2, a_name varchar2,
60-
a_line_no integer, a_expected_error_codes ut_integer_list := null, a_tags ut_varchar2_rows := null
60+
a_line_no integer, a_expected_error_codes ut_varchar2_rows := null, a_tags ut_varchar2_rows := null
6161
) return self as result,
6262
overriding member procedure mark_as_skipped(self in out nocopy ut_test),
6363
overriding member function do_execute(self in out nocopy ut_test) return boolean,

0 commit comments

Comments
 (0)