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

Skip to content
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
4 changes: 2 additions & 2 deletions client_source/sqlplus/ut_run.sql
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ set define &
/*
* Make SQLPlus parameters optional and pass parameters call to param_list variable
*/
@@define_params_variable.sql.tmp
@define_params_variable.sql.tmp



Expand Down Expand Up @@ -293,8 +293,8 @@ begin
p(' v_reporter.reporter_id := '''||l_reporter_id||''';');
p(' v_reporters_list.extend; v_reporters_list(v_reporters_list.last) := v_reporter;');
end loop;
close :l_run_params_cur;
end if;
close :l_run_params_cur;
p( ' ut_runner.run( ut_varchar2_list('||:l_paths||'), v_reporters_list, a_color_console => '||:l_color_enabled||' );');
p( 'end;');
p( '/');
Expand Down
2 changes: 1 addition & 1 deletion source/api/ut.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ create or replace package body ut is

procedure fail(a_message in varchar2) is
begin
ut_assert_processor.report_error(a_message);
ut_assert_processor.report_failure(a_message);
end;

procedure run_autonomous(a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer) is
Expand Down
96 changes: 62 additions & 34 deletions source/core/coverage/ut_coverage.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -39,57 +39,85 @@ create or replace package body ut_coverage is
return l_result;
end;

-- The source query has two important transformations done in it.
-- the flag: to_be_skipped ='Y' is set for a line of code that is badly reported by DBMS_PROFILER as executed 0 times.
-- This includes lines that are:
-- - PACKAGE, PROCEDURE, FUNCTION definition line,
-- - BEGIN, END of a block
-- Another transformation is adjustment of line number for TRIGGER body.
-- DBMS_PROFILER is reporting line numbers for triggers not as defined in DBA_SOURCE, its usign line numbers as defined in DBA_TRIGGERS
-- the DBA_TRIGGERS does not contain the trigger specification lines, only lines that define the trigger body.
-- the query adjusts the line numbers for triggers by finding first occurrence of begin|declare|compound in the trigger body line.
-- The subquery is optimized by:
-- - COALESCE function -> it will execute only for TRIGGERS
-- - scalar subquery cache -> it will only execute once for one trigger source code.
function get_sources_query return varchar2 is
l_result varchar2(32767);
l_full_name varchar2(100);
begin
l_result := 'insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)';
if g_file_mappings is not null then
l_result := 'insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
select f.file_name, s.owner,s.name,s.line,s.text,';
l_full_name := 'f.file_name';
else
l_result := 'insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
select lower(s.owner||''.''||s.name) as file_name, s.owner,s.name,s.line,s.text,';
l_full_name := 'lower(s.owner||''.''||s.name)';
end if;
l_result := l_result || q'[
case
when
-- to avoid execution of regexp_like on every line
-- first do a rough check for existence of search pattern keyword
(lower(s.text) like '%procedure%'
or lower(s.text) like '%function%'
or lower(s.text) like '%begin%'
or lower(s.text) like '%end%'
or lower(s.text) like '%package%'
) and
regexp_like(
s.text,
'^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(static|constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
)
then 'Y'
end as to_be_skipped
from all_source s]';
l_result := '
insert /*+ append */ into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
select *
from (
select '||l_full_name||q'[,
s.owner,
s.name,
s.line -
coalesce(
case when type!='TRIGGER' then 0 end,
(select min(t.line) - 1
from dba_source t
where t.owner = s.owner and t.type = s.type and t.name = s.name
and regexp_like( t.text, '\w*(begin|declare|compound).*','i'))
) as line,
s.text,
case
when
-- to avoid execution of regexp_like on every line
-- first do a rough check for existence of search pattern keyword
(lower(s.text) like '%procedure%'
or lower(s.text) like '%function%'
or lower(s.text) like '%begin%'
or lower(s.text) like '%end%'
or lower(s.text) like '%package%'
) and
regexp_like(
s.text,
'^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(static|constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
)
then 'Y'
end as to_be_skipped
from all_source s]';
if g_file_mappings is not null then
l_result := l_result || '
join table(:g_file_mappings) f
on s.name = f.object_name
and s.type = f.object_type
and s.owner = f.object_owner
where 1 = 1';
join table(:g_file_mappings) f
on s.name = f.object_name
and s.type = f.object_type
and s.owner = f.object_owner
where 1 = 1';
else
l_result := l_result || '
where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)';
where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)';
end if;
l_result := l_result || q'[
and s.type not in ('PACKAGE', 'TYPE')
--Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el)]';
and s.type not in ('PACKAGE', 'TYPE')
--Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el)]';
if g_include_list is null then
l_result := l_result || '
and :g_include_list is null';
and :g_include_list is null';
else
l_result := l_result || '
and (s.owner, s.name) in (select il.owner, il.name from table(:g_include_list) il)';
and (s.owner, s.name) in (select il.owner, il.name from table(:g_include_list) il)';
end if;
l_result := l_result || '
)
where line > 0';
return l_result;
end;
/**
Expand Down
5 changes: 1 addition & 4 deletions source/core/types/ut_assert_result.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,9 @@ create or replace type body ut_assert_result is
if a_clob is not null and l_text is not null then
l_text := chr(10) || l_text;
end if;
if l_text is not null then
dbms_lob.writeappend(a_clob, length(l_text), l_text);
end if;
ut_utils.append_to_clob(a_clob, l_text);
end;
begin
dbms_lob.createtemporary(l_result, true);
if self.result != ut_utils.tr_success or self.error_message is not null then
if self.message is not null then
add_text_line(l_result, ' expectation description: ', self.message);
Expand Down
60 changes: 21 additions & 39 deletions source/core/types/ut_executable.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,22 @@ create or replace type body ut_executable is
return self.procedure_name is not null and self.object_name is not null;
end;

member function is_valid return boolean is
l_result boolean := true;
member function is_valid(self in out nocopy ut_executable) return boolean is
l_result boolean := false;
l_message_part varchar2(4000) := 'Call params for ' || self.associated_event_name || ' are not valid: ';
begin

if self.object_name is null then
l_result := false;
ut_assert_processor.report_error('Call params for ' || self.associated_event_name || ' are not valid: package is not defined');
end if;

if self.procedure_name is null then
l_result := false;
ut_assert_processor.report_error('Call params for ' || self.associated_event_name || ' are not valid: procedure is not defined');
end if;

if l_result and not ut_metadata.package_valid(self.owner_name, self.object_name) then
l_result := false;
ut_assert_processor.report_error('Call params for ' || self.associated_event_name ||
' are not valid: package does not exist or is invalid: ' ||nvl(self.owner_name, '<missing schema name>')||'.'||
nvl(self.object_name, '<missing package name>'));
end if;

if l_result and not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.procedure_name) then
l_result := false;
ut_assert_processor.report_error('Call params for ' || self.associated_event_name || ' are not valid: package missing ' ||
' procedure ' || self.object_name || '.' ||
nvl(self.procedure_name, '<missing procedure name>'));
self.error_stack := l_message_part || 'package is not defined';
elsif not ut_metadata.package_valid(self.owner_name, self.object_name) then
self.error_stack := l_message_part || 'package does not exist or is invalid: ' ||upper(self.owner_name||'.'||self.object_name);
elsif self.procedure_name is null then
self.error_stack := l_message_part || 'procedure is not defined';
elsif not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.procedure_name) then
self.error_stack := l_message_part || 'package missing procedure '
|| upper(self.owner_name || '.' || self.object_name || '.' ||self.procedure_name);
else
l_result := true;
end if;

return l_result;
Expand All @@ -85,28 +75,16 @@ create or replace type body ut_executable is

l_completed_without_errors boolean := true;

function process_errors_from_call(a_error_stack varchar2, a_error_backtrace varchar2) return boolean is
l_errors_stack_trace varchar2(32767) := rtrim(a_error_stack||a_error_backtrace, chr(10));
begin
if l_errors_stack_trace is not null then
ut_utils.debug_log('test method failed- ' ||l_errors_stack_trace );
ut_assert_processor.report_error( l_errors_stack_trace );
return false;
else
return true;
end if;
end;

procedure save_dbms_output is
l_status number;
l_line varchar2(32767);
begin
dbms_lob.createtemporary(self.serveroutput, true, dur => dbms_lob.session);

loop
dbms_output.get_line(line => l_line, status => l_status);
exit when l_status = 1;

dbms_lob.writeappend(lob_loc => self.serveroutput,
amount => length(l_line),
buffer => l_line);
Expand Down Expand Up @@ -153,16 +131,20 @@ create or replace type body ut_executable is
dbms_sql.variable_value(l_cursor_number, 'a_error_stack', self.error_stack);
dbms_sql.variable_value(l_cursor_number, 'a_error_backtrace', self.error_backtrace);
dbms_sql.close_cursor(l_cursor_number);

save_dbms_output;

l_completed_without_errors := process_errors_from_call(self.error_stack, self.error_backtrace);
l_completed_without_errors := (self.error_stack||self.error_backtrace) is null;

a_listener.fire_after_event(self.associated_event_name, a_item);
--listener - after call to executable
end if;
return l_completed_without_errors;
end do_execute;

member function get_error_stack_trace return varchar2 is
begin
return rtrim(self.error_stack||self.error_backtrace, chr(10));
end;
end;
/
5 changes: 3 additions & 2 deletions source/core/types/ut_executable.tps
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ create or replace type ut_executable authid current_user as object(
error_stack varchar2(4000),
serveroutput clob,
constructor function ut_executable( self in out nocopy ut_executable, a_context ut_suite_item, a_procedure_name varchar2, a_associated_event_name varchar2) return self as result,
member function is_valid return boolean,
member function is_valid(self in out nocopy ut_executable) return boolean,
member function is_defined return boolean,
member function form_name return varchar2,
member procedure do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item, a_listener in out nocopy ut_event_listener_base),
Expand All @@ -35,6 +35,7 @@ create or replace type ut_executable authid current_user as object(
* returns true if executed without exceptions
* returns false if exceptions were raised
*/
member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item, a_listener in out nocopy ut_event_listener_base) return boolean
member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item, a_listener in out nocopy ut_event_listener_base) return boolean,
member function get_error_stack_trace return varchar2
) final
/
34 changes: 22 additions & 12 deletions source/core/types/ut_logical_suite.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ create or replace type body ut_logical_suite as
return;
end;

member function is_valid return boolean is
member function is_valid(self in out nocopy ut_logical_suite) return boolean is
begin
return true;
end;
Expand Down Expand Up @@ -58,14 +58,14 @@ create or replace type body ut_logical_suite as
l_completed_without_errors boolean;
begin
ut_utils.debug_log('ut_logical_suite.execute');

a_listener.fire_before_event(ut_utils.gc_suite,self);
self.start_time := current_timestamp;

if self.get_ignore_flag() then
self.result := ut_utils.tr_ignore;
a_listener.fire_before_event(ut_utils.gc_suite,self);
self.start_time := current_timestamp;

if self.get_disabled_flag() then
self.result := ut_utils.tr_disabled;
self.end_time := self.start_time;
ut_utils.debug_log('ut_logical_suite.execute - ignored');
ut_utils.debug_log('ut_logical_suite.execute - disabled');
else

self.start_time := current_timestamp;
Expand All @@ -79,7 +79,7 @@ create or replace type body ut_logical_suite as
self.end_time := current_timestamp;

end if;

a_listener.fire_after_event(ut_utils.gc_suite,self);

return l_completed_without_errors;
Expand All @@ -100,20 +100,30 @@ create or replace type body ut_logical_suite as

self.result := l_result;
end;
overriding member procedure fail(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base, a_failure_msg varchar2) is

overriding member procedure mark_as_errored(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base, a_error_stack_trace varchar2) is
begin
ut_utils.debug_log('ut_logical_suite.fail');
a_listener.fire_before_event(ut_utils.gc_suite, self);
self.start_time := current_timestamp;
for i in 1 .. self.items.count loop
-- execute the item (test or suite)
self.items(i).fail(a_listener,a_failure_msg);
self.items(i).mark_as_errored(a_listener, a_error_stack_trace);
end loop;
self.calc_execution_result();
self.end_time := self.start_time;
a_listener.fire_after_event(ut_utils.gc_suite, self);
end;
end;

overriding member function get_error_stack_traces return ut_varchar2_list is
begin
return ut_varchar2_list();
end;

overriding member function get_serveroutputs return clob is
begin
return null;
end;

end;
/
6 changes: 4 additions & 2 deletions source/core/types/ut_logical_suite.tps
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ create or replace type ut_logical_suite under ut_suite_item (
constructor function ut_logical_suite(
self in out nocopy ut_logical_suite,a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_description varchar2 := null, a_path varchar2
) return self as result,
member function is_valid return boolean,
member function is_valid(self in out nocopy ut_logical_suite) return boolean,
/**
* Finds the item in the suite by it's name and returns the item index
*/
member function item_index(a_name varchar2) return pls_integer,
member procedure add_item(self in out nocopy ut_logical_suite, a_item ut_suite_item),
overriding member function do_execute(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base) return boolean,
overriding member procedure calc_execution_result(self in out nocopy ut_logical_suite),
overriding member procedure fail(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base, a_failure_msg varchar2)
overriding member procedure mark_as_errored(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base, a_error_stack_trace varchar2),
overriding member function get_error_stack_traces return ut_varchar2_list,
overriding member function get_serveroutputs return clob
) not final
/
11 changes: 11 additions & 0 deletions source/core/types/ut_reporter_base.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ create or replace type body ut_reporter_base is
ut_output_buffer.send_line(self,a_text);
end;

member procedure print_clob(self in out nocopy ut_reporter_base, a_clob clob) is
l_lines ut_varchar2_list;
begin
if a_clob is not null and dbms_lob.getlength(a_clob) > 0 then
l_lines := ut_utils.clob_to_table(a_clob);
for i in 1 .. l_lines.count loop
self.print_text(l_lines(i));
end loop;
end if;
end;

-- run hooks
member procedure before_calling_run(self in out nocopy ut_reporter_base, a_run in ut_run) is
begin
Expand Down
2 changes: 2 additions & 0 deletions source/core/types/ut_reporter_base.tps
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ create or replace type ut_reporter_base authid current_user as object(

member procedure print_text(self in out nocopy ut_reporter_base, a_text varchar2),

member procedure print_clob(self in out nocopy ut_reporter_base, a_clob clob),

-- run hooks
member procedure before_calling_run(self in out nocopy ut_reporter_base, a_run in ut_run),

Expand Down
Loading