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

Skip to content

Commit 274af66

Browse files
committed
Added reporting of line where assertion has failed.
Addded separate example with demo of ut_documentation_reporter
1 parent 217c150 commit 274af66

11 files changed

Lines changed: 164 additions & 22 deletions

examples/RunAllExamples.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ prompt RunExampleTestAnnotationsHugePackage
2020
@@RunExampleTestAnnotationsHugePackage.sql
2121
prompt RunExpectations
2222
@@RunExpectations.sql
23+
prompt RunWithDocumentationReporter
24+
RunWithDocumentationReporter.sql

examples/RunExpectations.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
--Suite Management packages are when developed will make this easier.
44
--Clear Screen
55
Set Serveroutput On Size Unlimited format truncated
6-
set linesize 1000
6+
set linesize 10000
77
set echo off
88
--install the example unit test packages
99
@@department.tps
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
Set Serveroutput On Size Unlimited format truncated
2+
set linesize 10000
3+
set echo off
4+
5+
create or replace package demo_doc_reporter1 is
6+
-- %suite(Demo of documentation reporter)
7+
-- %test(A passing test sample)
8+
procedure passing_test;
9+
-- %test
10+
procedure test_without_name;
11+
-- %test(A failing test exsample)
12+
procedure failing_test;
13+
-- %test
14+
procedure failing_no_name;
15+
-- %test(repoting exception)
16+
procedure failing_exception_raised;
17+
end;
18+
/
19+
20+
create or replace package body demo_doc_reporter1 is
21+
22+
procedure passing_test is begin null; end;
23+
24+
procedure test_without_name is
25+
begin
26+
ut.expect(1).to_(equal(1));
27+
end;
28+
29+
procedure failing_test is
30+
begin
31+
ut.expect(1).to_(equal(2));
32+
end;
33+
procedure failing_no_name is
34+
begin
35+
ut.expect(sysdate).to_(equal(to_char(sysdate)));
36+
end;
37+
procedure failing_exception_raised is
38+
l_date date;
39+
begin
40+
l_date := to_date('abcd');
41+
end;
42+
end;
43+
/
44+
45+
create or replace package demo_doc_reporter2 is
46+
-- %suite(A suite pacakge without body)
47+
-- %test(A test)
48+
procedure passing_test1;
49+
-- %test
50+
procedure passing_test2;
51+
end;
52+
/
53+
54+
create or replace package suite_package_without_name is
55+
-- %suite
56+
-- %test(A passing test sample)
57+
procedure passing_test1;
58+
-- %test(A passing test sample)
59+
procedure passing_test2;
60+
end;
61+
/
62+
63+
create or replace package body suite_package_without_name is
64+
65+
procedure passing_test1 is begin null; end;
66+
67+
procedure passing_test2 is
68+
begin
69+
ut.expect(1).to_(equal(1));
70+
end;
71+
end;
72+
/
73+
74+
begin
75+
ut_suite_manager.run_cur_schema_suites_static(ut_documentation_reporter(), a_force_parse_again => true);
76+
end;
77+
/
78+
79+
80+
drop package demo_doc_reporter2;
81+
drop package suite_package_without_name;
82+
drop package demo_doc_reporter1;

source/core/types/ut_assert_result.tpb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ create or replace type body ut_assert_result is
77
self.object_type := 0;
88
self.result := a_result;
99
self.error_message := a_error_message;
10+
self.caller_info := ut_assert_processor.who_called_expectation();
1011
return;
1112
end ut_assert_result;
1213

@@ -24,6 +25,7 @@ create or replace type body ut_assert_result is
2425
self.actual_type := a_actual_type;
2526
self.expected_value_string := a_expected_value_string;
2627
self.actual_value_string := a_actual_value_string;
28+
self.caller_info := ut_assert_processor.who_called_expectation();
2729
return;
2830
end ut_assert_result;
2931

source/core/types/ut_assert_result.tps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ create or replace type ut_assert_result force under ut_object
77
actual_value_string varchar2(4000 char),
88
message varchar2(4000 char),
99
error_message varchar2(4000 char),
10+
caller_info varchar2(4000 char),
1011
constructor function ut_assert_result(self in out nocopy ut_assert_result, a_result integer, a_error_message varchar2, a_name varchar2 default null)
1112
return self as result,
1213
constructor function ut_assert_result(self in out nocopy ut_assert_result, a_name varchar2, a_additional_info varchar2, a_error_message varchar2,

source/core/types/ut_test.tpb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ create or replace type body ut_test is
7070
-- dbms_utility.format_error_backtrace is 10g or later
7171
-- utl_call_stack package may be better but it's 12c but still need to investigate
7272
-- article with details: http://www.oracle.com/technetwork/issue-archive/2014/14-jan/o14plsql-2045346.html
73-
ut_utils.debug_log('testmethod failed-' || sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace);
74-
75-
ut_assert_processor.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace);
73+
ut_utils.debug_log('test method failed-' || sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_stack || dbms_utility.format_error_backtrace);
74+
ut_assert_processor.report_error( dbms_utility.format_error_stack || dbms_utility.format_error_backtrace );
7675
end;
7776
a_reporter.after_test_execute(self);
7877

@@ -92,8 +91,7 @@ create or replace type body ut_test is
9291
end if;
9392
ut_utils.debug_log('ut_test.execute failed-' || sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace);
9493
-- most likely occured in setup or teardown if here.
95-
ut_assert_processor.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_stack);
96-
ut_assert_processor.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace);
94+
ut_assert_processor.report_error( dbms_utility.format_error_stack || dbms_utility.format_error_backtrace );
9795
end;
9896

9997
if self.rollback_type = ut_utils.gc_rollback_auto then

source/core/ut_assert_processor.pkb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,45 @@ create or replace package body ut_assert_processor as
111111

112112
end;
113113

114+
function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is
115+
l_line varchar2(4000);
116+
begin
117+
execute immediate
118+
q'[select text from dba_source
119+
where owner = :a_owner and name = :a_object_name and line = :a_line_no
120+
-- skip the declarations, consider only definitions
121+
and type not in ('PACKAGE', 'TYPE') ]'
122+
into l_line using a_owner, a_object_name, a_line_no;
123+
return '"'||ltrim(rtrim( lower( l_line ), chr(10) ))||'"';
124+
exception
125+
when no_data_found then
126+
return null;
127+
end;
128+
129+
function who_called_expectation return varchar2 is
130+
l_call_stack varchar2(32767) := dbms_utility.format_call_stack();
131+
l_caller_stack_line varchar2(4000);
132+
l_caller_type_and_name varchar2(4000);
133+
l_line_no integer;
134+
l_owner varchar2(100);
135+
l_object_name varchar2(100);
136+
l_last_space_pos integer;
137+
l_object_delimiter_pos integer;
138+
c_expectation_search_pattern constant varchar2(50) := '(.*\.UT_EXPECTATION[A-Z0-9#_$]*\s)+(.*)\s';
139+
begin
140+
l_caller_stack_line := regexp_substr( l_call_stack, c_expectation_search_pattern, 1, 1, 'm', 2);
141+
l_line_no := to_number( trim( substr( l_caller_stack_line, 11, 10 ) ) );
142+
l_caller_type_and_name := substr( l_caller_stack_line, 23 );
143+
l_last_space_pos := instr( l_caller_type_and_name, ' ', -1 );
144+
l_object_delimiter_pos := instr( l_caller_type_and_name, '.' );
145+
if l_object_delimiter_pos > 0 then
146+
l_owner := substr( l_caller_type_and_name, l_last_space_pos + 1, l_object_delimiter_pos - l_last_space_pos - 1 );
147+
l_object_name := substr( l_caller_type_and_name, l_object_delimiter_pos + 1 );
148+
end if;
149+
return
150+
case when l_owner is not null and l_object_name is not null and l_line_no is not null then
151+
'at "'||l_owner||'.'||l_object_name||'", line '||l_line_no||' '||get_source_definition_line(l_owner, l_object_name, l_line_no)
152+
end;
153+
end;
114154
end;
115155
/

source/core/ut_assert_processor.pks

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,13 @@ create or replace package ut_assert_processor authid current_user as
2222

2323
procedure reset_nls_params;
2424

25+
-- function is looking at call stack
26+
-- and tries to figure out at which line of code
27+
-- in a unit test, the expectation was called
28+
-- if found, it returns a text:
29+
-- at: owner.name:line "source code line text"
30+
-- The text is to be consumed by expectation result
31+
function who_called_expectation return varchar2;
32+
2533
end;
2634
/

source/core/ut_utils.pkb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ create or replace package body ut_utils is
8181
case
8282
when l_len = 0 then gc_null_string
8383
when l_len <= gc_max_input_string_length then quote_string(rawtohex(a_value))
84-
else to_string( rawtohex(dbms_lob.substr(a_value, gc_overflow_substr_len)) )
84+
else quote_string( rawtohex(dbms_lob.substr(a_value, gc_overflow_substr_len)) )
8585
end;
8686
end;
8787

@@ -135,5 +135,10 @@ create or replace package body ut_utils is
135135
extract(second from(a_end_time - a_start_time));
136136
end;
137137

138+
function indent_lines(a_text varchar2, a_indent_size integer) return varchar2 is
139+
begin
140+
return replace( a_text, chr(10), chr(10) || lpad( ' ', a_indent_size ) );
141+
end;
142+
138143
end ut_utils;
139144
/

source/core/ut_utils.pks

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,7 @@ create or replace package ut_utils authid definer is
9090

9191
function time_diff(a_start_time timestamp with time zone, a_end_time timestamp with time zone) return number;
9292

93+
function indent_lines(a_text varchar2, a_indent_size integer) return varchar2;
94+
9395
end ut_utils;
9496
/

0 commit comments

Comments
 (0)