@@ -90,6 +90,9 @@ create or replace package body ut_expectation_processor as
9090 for i in 1 .. l_results.count loop
9191 dbms_output.put_line( ' ' || l_results(i) );
9292 end loop;
93+ if a_expectation_result.caller_info is not null then
94+ dbms_output.put_line( ut_utils.indent_lines( a_expectation_result.caller_info, 2, true) );
95+ end if;
9396 end if;
9497 end;
9598
@@ -147,28 +150,55 @@ create or replace package body ut_expectation_processor as
147150
148151 function who_called_expectation(a_call_stack varchar2) return varchar2 is
149152 l_caller_stack_line varchar2(4000);
153+ l_call_stack varchar2(4000);
150154 l_line_no integer;
151155 l_owner varchar2(1000);
152156 l_object_name varchar2(1000);
153- l_object_full_name varchar2(1000);
154157 l_result varchar2(4000);
155158 -- in 12.2 format_call_stack reportes not only package name, but also the procedure name
156159 -- when 11g and 12c reports only package name
157- c_expectation_search_pattern constant varchar2(500) :=
158- '(.*\.(UT_EXPECTATION[A-Z0-9#_$]*|UT|UTASSERT2?)(\.[A-Z0-9#_$]+)?\s+)+(.*)';
160+ function cut_header_and_expectations( a_stack varchar2 ) return varchar2 is
161+ begin
162+ return regexp_substr( a_stack, '(.*\.(UT_EXPECTATION[A-Z0-9#_$]*|UT|UTASSERT2?)(\.[A-Z0-9#_$]+)?\s+)+((.|\s)*)', 1, 1, 'm', 4);
163+ end;
164+ function cut_address_columns( a_stack varchar2 ) return varchar2 is
165+ begin
166+ return regexp_replace( a_stack, '^(0x)?[0-9a-f]+\s+', '', 1, 0, 'm' );
167+ end;
168+ function cut_framework_stack( a_stack varchar2 ) return varchar2 is
169+ begin
170+ return regexp_replace(
171+ a_stack,
172+ '[0-9]+\s+anonymous\s+block\s+[0-9]+\s+package\s+body\s+sys\.dbms_sql(\.execute)?\s+[0-9]+\s+[0-9_$#a-z ]+\.ut_executable.*',
173+ '',
174+ 1, 1, 'mni'
175+ );
176+ end;
177+ function format_stack( a_stack varchar2 ) return varchar2 is
178+ begin
179+ return regexp_replace(
180+ a_stack,
181+ '([0-9]+)\s+(.* )?((anonymous block)|(([0-9_$#a-z]+\.[0-9_$#a-z]+(\.([0-9_$#a-z])+)?)))',
182+ 'at "\3", line \1', 1, 0, 'i'
183+ );
184+ end;
159185 begin
160- l_caller_stack_line := regexp_substr( a_call_stack, c_expectation_search_pattern, 1, 1, 'm', 4);
186+ l_call_stack := cut_header_and_expectations( a_call_stack );
187+ l_call_stack := cut_address_columns( l_call_stack );
188+ l_call_stack := cut_framework_stack( l_call_stack );
189+ l_call_stack := format_stack( l_call_stack );
190+ l_caller_stack_line := regexp_substr(l_call_stack,'^(.*)');
161191 if l_caller_stack_line like '%.%' then
162- l_line_no := to_number( regexp_substr(l_caller_stack_line,'(0x)?[0-9a-f]+\s+(\ d+)',subexpression => 2 ) );
163- l_owner := regexp_substr(l_caller_stack_line,' ([A-Za-z0-9$#_]+)\.([A-Za-z0-9$#_]|\.)+', subexpression => 1);
164- l_object_name := regexp_substr(l_caller_stack_line,' ([A-Za-z0-9$#_]+)\.([A-Za-z0-9$#_]+)', subexpression => 2 );
165- l_object_full_name := regexp_substr(l_caller_stack_line,'([A-Za-z0-9$#_]+)\.(([A-Za-z0-9$#_]|\.)+)',subexpression => 2);
166- if l_owner is not null and l_object_name is not null and l_line_no is not null then
167- l_result := 'at "' || l_owner || '.' || l_object_full_name || '", line '|| l_line_no || ' '
168- || ut_metadata.get_source_definition_line(l_owner, l_object_name, l_line_no);
169- end if ;
192+ l_line_no := to_number( regexp_substr( l_caller_stack_line, ', line (\ d+)', subexpression => 1 ) );
193+ l_owner := regexp_substr( l_caller_stack_line, 'at " ([A-Za-z0-9$#_]+)\.(( [A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?)", line (\d+)', subexpression => 1 );
194+ l_object_name := regexp_substr( l_caller_stack_line, 'at " ([A-Za-z0-9$#_]+)\.(( [A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?)", line (\d+)', subexpression => 3 );
195+ l_result :=
196+ l_caller_stack_line || ' ' || rtrim(ut_metadata.get_source_definition_line(l_owner, l_object_name, l_line_no),chr(10))
197+ || replace( l_call_stack, l_caller_stack_line );
198+ else
199+ l_result := l_call_stack ;
170200 end if;
171- return l_result;
201+ return rtrim( l_result,chr(10)) ;
172202 end;
173203
174204 procedure add_warning(a_messsage varchar2) is
0 commit comments