8000 Moved validation of `--%throws` annotation values. by jgebal · Pull Request #1038 · utPLSQL/utPLSQL · GitHub
[go: up one dir, main page]

Skip to content

Moved validation of --%throws annotation values. #1038

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

Merged
merged 1 commit into from
Jan 3, 2020
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
114 changes: 109 additions & 5 deletions source/core/types/ut_executable_test.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ create or replace type body ut_executable_test as

member procedure do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
a_expected_error_codes in ut_integer_list
a_expected_error_codes in ut_varchar2_rows
) is
l_completed_without_errors boolean;
begin
Expand All @@ -40,10 +40,114 @@ create or replace type body ut_executable_test as

member function do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
a_expected_error_codes in ut_integer_list
a_expected_error_codes in ut_varchar2_rows
) return boolean is
l_expected_except_message varchar2(4000);
l_expected_error_numbers ut_integer_list;

function build_exception_numbers_list(
a_item in out nocopy ut_suite_item,
a_expected_error_codes in ut_varchar2_rows
) return ut_integer_list is
l_exception_number integer;
l_exception_number_list ut_integer_list := ut_integer_list();
c_regexp_for_exception_no constant varchar2(30) := '^-?[[:digit:]]{1,5}$';

c_integer_exception constant varchar2(1) := 'I';
c_named_exception constant varchar2(1) := 'N';

function is_valid_qualified_name (a_name varchar2) return boolean is
l_name varchar2(500);
begin
l_name := dbms_assert.qualified_sql_name(a_name);
return true;
exception when others then
return false;
end;

function check_exception_type(a_exception_name in varchar2) return varchar2 is
l_exception_type varchar2(50);
begin
--check if it is a predefined exception
begin
execute immediate 'begin null; exception when '||a_exception_name||' then null; end;';
l_exception_type := c_named_exception;
exception
when others then
if dbms_utility.format_error_stack() like '%PLS-00485%' then
declare
e_invalid_number exception;
pragma exception_init ( e_invalid_number, -6502 );
begin
execute immediate 'declare x integer := '||a_exception_name||'; begin null; end;';
l_exception_type := c_integer_exception;
exception
when others then
null;
end;
end if;
end;
return l_exception_type;
end;

function get_exception_number (a_exception_var in varchar2) return integer is
l_exc_no integer;
l_exc_type varchar2(50);
function remap_no_data_found (a_number integer) return integer is
begin
return case a_number when 100 then -1403 else a_number end;
end;
begin
l_exc_type := check_exception_type(a_exception_var);

execute immediate
case l_exc_type
when c_integer_exception then
'declare l_exception number; begin :l_exception := '||a_exception_var||'; end;'
when c_named_exception then
'begin raise '||a_exception_var||'; exception when others then :l_exception := sqlcode; end;'
else
'begin :l_exception := null; end;'
end
using out l_exc_no;

return remap_no_data_found(l_exc_no);
end;

begin
if a_expected_error_codes is not empty then
for i in 1 .. a_expected_error_codes.count loop
/**
* Check if its a valid qualified name and if so try to resolve name to an exception number
*/
if is_valid_qualified_name(a_expected_error_codes(i)) then
l_exception_number := get_exception_number(a_expected_error_codes(i));
elsif regexp_like(a_expected_error_codes(i), c_regexp_for_exception_no) then
l_exception_number := a_expected_error_codes(i);
end if;

if l_exception_number is null then
a_item.put_warning(
'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Parameter ignored.',
self.procedure_name,
a_item.line_no
);
elsif l_exception_number >= 0 then
a_item.put_warning(
'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Exception value must be a negative integer. Parameter ignored.',
self.procedure_name,
a_item.line_no
);
else
l_exception_number_list.extend;
l_exception_number_list(l_exception_number_list.last) := l_exception_number;
end if;
l_exception_number := null;
end loop;
end if;

return l_exception_number_list;
end;
function failed_expec_errnum_message(a_expected_error_codes in ut_integer_list) return varchar is
l_actual_error_no integer;
l_expected_error_codes varchar2(4000);
Expand Down Expand Up @@ -72,9 +176,9 @@ create or replace type body ut_executable_test as
begin
--Create a ut_executable object and call do_execute after that get the data to know the test's execution result
self.do_execute(a_item);

if a_expected_error_codes is not null and a_expected_error_codes is not empty then
l_expected_except_message := failed_expec_errnum_message(a_expected_error_codes);
l_expected_error_numbers := build_exception_numbers_list(a_item, a_expected_error_codes);
if l_expected_error_numbers is not null and l_expected_error_numbers is not empty then
l_expected_except_message := failed_expec_errnum_message( l_expected_error_numbers );

if l_expected_except_message is not null then
ut_expectation_processor.add_expectation_result(
Expand Down
4 changes: 2 additions & 2 deletions source/core/types/ut_executable_test.tps
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ create or replace type ut_executable_test authid current_user under ut_executabl

member procedure do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
a_expected_error_codes in ut_integer_list
a_expected_error_codes in ut_varchar2_rows
),

member function do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
a_expected_error_codes in ut_integer_list
a_expected_error_codes in ut_varchar2_rows
) return boolean

) final;
Expand Down
2 changes: 1 addition & 1 deletion source/core/types/ut_suite_cache_row.tps
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ create type ut_suite_cache_row as object (
before_test_list ut_executables,
after_each_list ut_executables,
after_test_list ut_executables,
expected_error_codes ut_integer_list,
expected_error_codes ut_varchar2_rows,
tags ut_varchar2_rows,
item ut_executable_test
)
Expand Down
10 changes: 10 additions & 0 deletions source/core/types/ut_suite_item.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ create or replace type body ut_suite_item as
self.results_count.increase_warning_count;
end;

member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2, a_procedure_name varchar2, a_line_no integer) is
l_result varchar2(1000);
begin
l_result := self.object_owner || '.' || self.object_name ;
if a_procedure_name is not null then
l_result := l_result || '.' || a_procedure_name ;
end if;
put_warning( a_message || chr( 10 ) || 'at package "' || upper(l_result) || '", line ' || a_line_no );
end;

member function get_transaction_invalidators return ut_varchar2_list is
begin
return transaction_invalidators;
Expand Down
3 changes: 2 additions & 1 deletion source/core/types/ut_suite_item.tps
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ create or replace type ut_suite_item force under ut_event_item (
not instantiable member procedure mark_as_errored(self in out nocopy ut_suite_item, a_error_stack_trace varchar2),
not instantiable member function get_error_stack_traces return ut_varchar2_list,
not instantiable member function get_serveroutputs return clob,
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2)
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2),
member procedure put_warning(self in out nocopy ut_suite_item, a_message varchar2, a_procedure_name varchar2, a_line_no integer)
)
not final not instantiable
/
2 changes: 1 addition & 1 deletion source/core/types/ut_test.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ create or replace type body ut_test as

constructor function ut_test(
self in out nocopy ut_test, a_object_owner varchar2 := null, a_object_name varchar2, a_name varchar2,
a_line_no integer, a_expected_error_codes ut_integer_list := null, a_tags ut_varchar2_rows := null
a_line_no integer, a_expected_error_codes ut_varchar2_rows := null, a_tags ut_varchar2_rows := null
) return self as result is
begin
self.self_type := $$plsql_unit;
Expand Down
4 changes: 2 additions & 2 deletions source/core/types/ut_test.tps
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ create or replace type ut_test force under ut_suite_item (
/**
*Holds the expected error codes list when the user use the annotation throws
*/
expected_error_codes ut_integer_list,
expected_error_codes ut_varchar2_rows,
constructor function ut_test(
self in out nocopy ut_test, a_object_owner varchar2 := null, a_object_name varchar2, a_name varchar2,
a_line_no integer, a_expected_error_codes ut_integer_list := null, a_tags ut_varchar2_rows := null
a_line_no integer, a_expected_error_codes ut_varchar2_rows := null, a_tags ut_varchar2_rows := null
) return self as result,
overriding member procedure mark_as_skipped(self in out nocopy ut_test),
overriding member function do_execute(self in out nocopy ut_test) return boolean,
Expand Down
Loading
0