From 2560f5b7c12c8562010ff92e3bcb24588e16ca81 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 25 Mar 2018 18:04:26 +0100 Subject: [PATCH] Revert "Feature/12cblockcoverage" --- source/core/coverage/ut_block_helper.pkb | 89 ----- source/core/coverage/ut_block_helper.pks | 26 -- source/core/coverage/ut_coverage.pkb | 306 +++++++++++++++++- source/core/coverage/ut_coverage.pks | 7 +- source/core/coverage/ut_coverage_block.pkb | 224 ------------- source/core/coverage/ut_coverage_block.pks | 22 -- source/core/coverage/ut_coverage_helper.pkb | 130 ++++++-- source/core/coverage/ut_coverage_helper.pks | 11 +- source/core/coverage/ut_coverage_proftab.pkb | 178 ---------- source/core/coverage/ut_coverage_proftab.pks | 22 -- source/core/coverage/ut_proftab_helper.pkb | 93 ------ source/core/coverage/ut_proftab_helper.pks | 30 -- source/core/types/ut_run.tpb | 2 +- source/install.sql | 16 +- .../reporters/ut_block_report_html_helper.pkb | 226 ------------- .../reporters/ut_block_report_html_helper.pks | 21 -- .../ut_coverage_report_html_helper.pkb | 259 ++++++++++++++- .../ut_coverage_report_html_helper.pks | 14 - .../ut_proftab_report_html_helper.pkb | 210 ------------ .../ut_proftab_report_html_helper.pks | 21 -- 20 files changed, 659 insertions(+), 1248 deletions(-) delete mode 100644 source/core/coverage/ut_block_helper.pkb delete mode 100644 source/core/coverage/ut_block_helper.pks delete mode 100644 source/core/coverage/ut_coverage_block.pkb delete mode 100644 source/core/coverage/ut_coverage_block.pks delete mode 100644 source/core/coverage/ut_coverage_proftab.pkb delete mode 100644 source/core/coverage/ut_coverage_proftab.pks delete mode 100644 source/core/coverage/ut_proftab_helper.pkb delete mode 100644 source/core/coverage/ut_proftab_helper.pks delete mode 100644 source/reporters/ut_block_report_html_helper.pkb delete mode 100644 source/reporters/ut_block_report_html_helper.pks delete mode 100644 source/reporters/ut_proftab_report_html_helper.pkb delete mode 100644 source/reporters/ut_proftab_report_html_helper.pks diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_helper.pkb deleted file mode 100644 index f0c2322ab..000000000 --- a/source/core/coverage/ut_block_helper.pkb +++ /dev/null @@ -1,89 +0,0 @@ -create or replace package body ut_block_helper is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - type t_proftab_row is record ( - line binary_integer, - calls number(38,0) - ); - - type t_proftab_rows is table of t_proftab_row; - - type t_block_row is record( - line binary_integer - ,blocks binary_integer - ,covered_blocks binary_integer); - - type t_block_rows is table of t_block_row; - - procedure coverage_start(a_run_comment varchar2,a_coverage_id out integer) is - begin - a_coverage_id := dbms_plsql_code_coverage.start_coverage(run_comment => a_run_comment); - end; - - procedure coverage_stop is - begin - dbms_plsql_code_coverage.stop_coverage(); - end; - - function block_results(a_object_owner varchar2, a_object_name varchar2) return t_block_rows is - c_raw_coverage sys_refcursor; - l_coverage_rows t_block_rows; - l_coverage_id integer := ut_coverage_helper.get_coverage_id; - begin - open c_raw_coverage for q'[select ccb.line - ,count(ccb.block) totalblocks - ,sum(ccb.covered) - from dbmspcc_units ccu - left outer join dbmspcc_blocks ccb - on ccu.run_id = ccb.run_id - and ccu.object_id = ccb.object_id - where ccu.run_id = :a_coverage_id - and ccu.owner = :a_object_owner - and ccu.name = :a_object_name - group by ccb.line - order by 1]' using l_coverage_id,a_object_owner,a_object_name; - - fetch c_raw_coverage bulk collect into l_coverage_rows; - close c_raw_coverage; - - return l_coverage_rows; - end; - - function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls is - l_tmp_data t_block_rows; - l_results ut_coverage_helper.t_unit_line_calls; - - begin - l_tmp_data := block_results(a_object_owner => a_object_owner, a_object_name => a_object_name); - for i in 1 .. l_tmp_data.count loop - l_results(l_tmp_data(i).line).blocks := l_tmp_data(i).blocks; - l_results(l_tmp_data(i).line).covered_blocks := l_tmp_data(i).covered_blocks; - l_results(l_tmp_data(i).line).partcovered := case - when (l_tmp_data(i).covered_blocks > 0) and - (l_tmp_data(i).blocks > l_tmp_data(i).covered_blocks) then - 1 - else - 0 - end; - end loop; - return l_results; - end; - - -end; -/ diff --git a/source/core/coverage/ut_block_helper.pks b/source/core/coverage/ut_block_helper.pks deleted file mode 100644 index eef041275..000000000 --- a/source/core/coverage/ut_block_helper.pks +++ /dev/null @@ -1,26 +0,0 @@ -create or replace package ut_block_helper authid definer is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - procedure coverage_start(a_run_comment in varchar2,a_coverage_id out integer); - - procedure coverage_stop; - - function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls; - -end; -/ diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 4ca1ff056..d09a672be 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -19,7 +19,84 @@ create or replace package body ut_coverage is type t_source_lines is table of binary_integer; - function get_cov_sources_cursor(a_coverage_options in ut_coverage_options,a_sql in varchar2) return sys_refcursor is + -- 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_cov_sources_sql(a_coverage_options ut_coverage_options) return varchar2 is + l_result varchar2(32767); + l_full_name varchar2(100); + l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_source'); + begin + if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then + l_full_name := 'f.file_name'; + else + l_full_name := 'lower(s.owner||''.''||s.name)'; + end if; + l_result := ' + select full_name, owner, name, line, to_be_skipped, text + from ( + select '||l_full_name||q'[ as full_name, + s.owner, + s.name, + s.line - + coalesce( + case when type!='TRIGGER' then 0 end, + (select min(t.line) - 1 + from ]'||l_view_name||q'[ t + where t.owner = s.owner and t.type = s.type and t.name = s.name + and regexp_like( t.text, '[A-Za-z0-9$#_]*(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, + '^([\t ]*(((not)?\s*(overriding|final|instantiable)[\t ]*)*(static|constructor|member)?[\t ]*(procedure|function)|package([\t ]+body)|begin|end([\t ]+\S+)*[ \t]*;))', 'i' + ) + then 'Y' + end as to_be_skipped + from ]'||l_view_name||q'[ s]'; + if a_coverage_options.file_mappings is not empty then + l_result := l_result || ' + join table(:file_mappings) f + on s.name = f.object_name + and s.type = f.object_type + and s.owner = f.object_owner + where 1 = 1'; + elsif a_coverage_options.include_objects is not empty then + l_result := l_result || ' + where (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)'; + else + l_result := l_result || ' + 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', 'JAVA SOURCE') + --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) + ) + where line > 0]'; + return l_result; + end; + + function get_cov_sources_cursor(a_coverage_options ut_coverage_options) return sys_refcursor is l_cursor sys_refcursor; l_skip_objects ut_object_names; l_schema_names ut_varchar2_rows; @@ -30,7 +107,7 @@ create or replace package body ut_coverage is --skip all the utplsql framework objects and all the unit test packages that could potentially be reported by coverage. l_skip_objects := ut_utils.get_utplsql_objects_list() multiset union all coalesce(a_coverage_options.exclude_objects, ut_object_names()); end if; - l_sql := a_sql; + l_sql := get_cov_sources_sql(a_coverage_options); if a_coverage_options.file_mappings is not empty then open l_cursor for l_sql using a_coverage_options.file_mappings, l_skip_objects; elsif a_coverage_options.include_objects is not empty then @@ -41,7 +118,7 @@ create or replace package body ut_coverage is return l_cursor; end; - procedure populate_tmp_table(a_coverage_options in ut_coverage_options,a_sql in varchar2) is + procedure populate_tmp_table(a_coverage_options ut_coverage_options) is pragma autonomous_transaction; l_cov_sources_crsr sys_refcursor; l_cov_sources_data ut_coverage_helper.t_coverage_sources_tmp_rows; @@ -50,7 +127,7 @@ create or replace package body ut_coverage is if not ut_coverage_helper.is_tmp_table_populated() or ut_coverage_helper.is_develop_mode() then ut_coverage_helper.cleanup_tmp_table(); - l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options,a_sql); + l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options); loop fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 1000; @@ -70,13 +147,13 @@ create or replace package body ut_coverage is * Public functions */ procedure coverage_start(a_coverage_options ut_coverage_options default null) is - l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab'); begin ut_coverage_helper.coverage_start('utPLSQL Code coverage run '||ut_utils.to_string(systimestamp),l_coverage_type); end; procedure coverage_start_develop(a_coverage_options ut_coverage_options default null) is - l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab'); begin ut_coverage_helper.coverage_start_develop(l_coverage_type); end; @@ -101,13 +178,224 @@ create or replace package body ut_coverage is ut_coverage_helper.coverage_stop_develop(); end; + function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return t_coverage is + l_line_calls ut_coverage_helper.t_unit_line_calls; + l_result t_coverage; + l_new_unit t_unit_coverage; + line_no binary_integer; + l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; + l_source_object ut_coverage_helper.t_tmp_table_object; + begin + + --prepare global temp table with sources + populate_tmp_table(a_coverage_options); + + l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); + loop + fetch l_source_objects_crsr into l_source_object; + exit when l_source_objects_crsr%notfound; + + --get coverage data + l_line_calls := ut_coverage_helper.get_raw_coverage_data_profiler( l_source_object.owner, l_source_object.name ); + + --if there is coverage, we need to filter out the garbage (badly indicated data from dbms_profiler) + if l_line_calls.count > 0 then + --remove lines that should not be indicted as meaningful + for i in 1 .. l_source_object.to_be_skipped_list.count loop + if l_source_object.to_be_skipped_list(i) is not null then + l_line_calls.delete(l_source_object.to_be_skipped_list(i)); + end if; + end loop; + end if; + + --if there are no file mappings or object was actually captured by profiler + if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then + + --populate total stats + l_result.total_lines := l_result.total_lines + l_source_object.lines_count; + + --populate object level coverage stats + if not l_result.objects.exists(l_source_object.full_name) then + l_result.objects(l_source_object.full_name) := l_new_unit; + l_result.objects(l_source_object.full_name).owner := l_source_object.owner; + l_result.objects(l_source_object.full_name).name := l_source_object.name; + l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count; + end if; + --map to results + line_no := l_line_calls.first; + if line_no is null then + l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count; + l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count; + else + loop + exit when line_no is null; + + if l_line_calls(line_no).calls > 0 then + --total stats + l_result.covered_lines := l_result.covered_lines + 1; + l_result.executions := l_result.executions + l_line_calls(line_no).calls; + --object level stats + l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name).covered_lines + 1; + l_result.objects(l_source_object.full_name).executions := l_result.objects(l_source_object.full_name).executions + l_line_calls(line_no).calls; + elsif l_line_calls(line_no).calls = 0 then + l_result.uncovered_lines := l_result.uncovered_lines + 1; + l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name).uncovered_lines + 1; + end if; + l_result.objects(l_source_object.full_name).lines(line_no).executions := l_line_calls(line_no).calls; + + line_no := l_line_calls.next(line_no); + end loop; + end if; + end if; + + end loop; + + close l_source_objects_crsr; + + return l_result; + end get_coverage_data_profiler; + + function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is + l_line_calls ut_coverage_helper.t_unit_line_calls; + l_result ut_coverage.t_coverage; + l_new_unit ut_coverage.t_unit_coverage; + line_no binary_integer; + l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; + l_source_object ut_coverage_helper.t_tmp_table_object; + begin + --prepare global temp table with sources + populate_tmp_table(a_coverage_options); + + l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); + loop + fetch l_source_objects_crsr + into l_source_object; + exit when l_source_objects_crsr%notfound; + + --get coverage data + l_line_calls := ut_coverage_helper.get_raw_coverage_data_block(l_source_object.owner, l_source_object.name); + + --if there is coverage, we need to filter out the garbage (badly indicated data) + if l_line_calls.count > 0 then + --remove lines that should not be indicted as meaningful + for i in 1 .. l_source_object.to_be_skipped_list.count loop + if l_source_object.to_be_skipped_list(i) is not null then + l_line_calls.delete(l_source_object.to_be_skipped_list(i)); + end if; + end loop; + end if; + + --if there are no file mappings or object was actually captured by profiler + if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then + + --populate total stats + l_result.total_lines := l_result.total_lines + l_source_object.lines_count; + + --populate object level coverage stats + if not l_result.objects.exists(l_source_object.full_name) then + l_result.objects(l_source_object.full_name) := l_new_unit; + l_result.objects(l_source_object.full_name).owner := l_source_object.owner; + l_result.objects(l_source_object.full_name).name := l_source_object.name; + l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count; + end if; + --map to results + line_no := l_line_calls.first; + if line_no is null then + l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count; + l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count; + else + loop + exit when line_no is null; + + --turn the block coverage into a line coverage format to allow for reading. + --whenever the linst is a part covered treat that line as a hit and execution but only part covered + + --total stats + --Get total blocks ,blocks covered, blocks not covered this will be used for PCT calc + l_result.total_blocks := nvl(l_result.total_blocks, 0) + l_line_calls(line_no).blocks; + l_result.covered_blocks := nvl(l_result.covered_blocks, 0) + l_line_calls(line_no).covered_blocks; + l_result.uncovered_blocks := nvl(l_result.uncovered_blocks, 0) + + (l_line_calls(line_no).blocks - l_line_calls(line_no).covered_blocks); + + --If line is partially covered add as part line cover and covered for line reporter + if l_line_calls(line_no).partcovered = 1 then + l_result.partcovered_lines := l_result.partcovered_lines + 1; + end if; + + if l_line_calls(line_no).covered_blocks > 0 then + l_result.covered_lines := l_result.covered_lines + 1; + end if; + + -- Use nvl as be default is null and screw the calcs + --Increase total blocks + l_result.objects(l_source_object.full_name).lines(line_no).no_blocks := l_line_calls(line_no).blocks; + l_result.objects(l_source_object.full_name).lines(line_no).covered_blocks := l_line_calls(line_no).covered_blocks; + l_result.objects(l_source_object.full_name).total_blocks := nvl(l_result.objects(l_source_object.full_name) + .total_blocks + ,0) + l_line_calls(line_no).blocks; + + --Total uncovered blocks is a line blocks minus covered blocsk + l_result.objects(l_source_object.full_name).uncovered_blocks := nvl(l_result.objects(l_source_object.full_name) + .uncovered_blocks + ,0) + + (l_line_calls(line_no).blocks - l_line_calls(line_no) + .covered_blocks); + + --If we have any covered blocks in line + if l_line_calls(line_no).covered_blocks > 0 then + --If any block is covered then we have a hit on that line + l_result.executions := l_result.executions + 1; + --object level stats + --If its part covered then mark it else treat as full cov + if l_line_calls(line_no).partcovered = 1 then + l_result.objects(l_source_object.full_name).partcovered_lines := l_result.objects(l_source_object.full_name) + .partcovered_lines + 1; + end if; + l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) + .covered_lines + 1; + + --How many blocks we covered + l_result.objects(l_source_object.full_name).covered_blocks := nvl(l_result.objects(l_source_object.full_name) + .covered_blocks + ,0) + l_line_calls(line_no) + .covered_blocks; + + --Object line executions + l_result.objects(l_source_object.full_name).executions := nvl(l_result.objects(l_source_object.full_name) + .executions + ,0) + 1; + + l_result.objects(l_source_object.full_name).lines(line_no).executions := 1; + + --Whenever there is no covered block treat as uncovered (query returns only lines where the blocks are in code so we + --dont have a false results here when there is no blocks + elsif l_line_calls(line_no).covered_blocks = 0 then + l_result.uncovered_lines := l_result.uncovered_lines + 1; + l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name) + .uncovered_lines + 1; + l_result.objects(l_source_object.full_name).lines(line_no).executions := 0; + end if; + --increase part covered counter (+ 1/0) + l_result.objects(l_source_object.full_name).lines(line_no).partcove := l_line_calls(line_no).partcovered; + line_no := l_line_calls.next(line_no); + end loop; + end if; + end if; + + end loop; + + close l_source_objects_crsr; + + return l_result; + end get_coverage_data_block; + function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is begin - if a_coverage_options.coverage_type = c_block_coverage then - return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + if a_coverage_options.coverage_type = 'block' then + return get_coverage_data_block(a_coverage_options => a_coverage_options); else - return ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); + return get_coverage_data_profiler(a_coverage_options => a_coverage_options); end if; end get_coverage_data; diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index db659c049..8a7df49ed 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -15,10 +15,7 @@ create or replace package ut_coverage authid current_user is See the License for the specific language governing permissions and limitations under the License. */ - - c_proftab_coverage constant varchar2(32) := 'proftab'; - c_block_coverage constant varchar2(32) := 'block'; - + -- total run coverage information subtype t_full_name is varchar2(4000); subtype t_object_name is varchar2(250); @@ -62,8 +59,6 @@ create or replace package ut_coverage authid current_user is ,executions number(38, 0) := 0 ,objects tt_program_units); - procedure populate_tmp_table(a_coverage_options ut_coverage_options, a_sql in varchar2); - procedure coverage_start(a_coverage_options ut_coverage_options default null); /* diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb deleted file mode 100644 index a5a9801c8..000000000 --- a/source/core/coverage/ut_coverage_block.pkb +++ /dev/null @@ -1,224 +0,0 @@ -create or replace package body ut_coverage_block is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - - type t_source_lines is table of binary_integer; - - -- 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_cov_sources_sql(a_coverage_options ut_coverage_options) return varchar2 is - l_result varchar2(32767); - l_full_name varchar2(100); - l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_source'); - begin - if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then - l_full_name := 'f.file_name'; - else - l_full_name := 'lower(s.owner||''.''||s.name)'; - end if; - l_result := ' - select full_name, owner, name, line, to_be_skipped, text - from ( - select '||l_full_name||q'[ as full_name, - s.owner, - s.name, - s.line - - coalesce( - case when type!='TRIGGER' then 0 end, - (select min(t.line) - 1 - from ]'||l_view_name||q'[ t - where t.owner = s.owner and t.type = s.type and t.name = s.name - and regexp_like( t.text, '[A-Za-z0-9$#_]*(begin|declare|compound).*','i')) - ) as line, - s.text, 'N' as to_be_skipped - from ]'||l_view_name||q'[ s]'; - - if a_coverage_options.file_mappings is not empty then - l_result := l_result || ' - join table(:file_mappings) f - on s.name = f.object_name - and s.type = f.object_type - and s.owner = f.object_owner - where 1 = 1'; - elsif a_coverage_options.include_objects is not empty then - l_result := l_result || ' - where (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)'; - else - l_result := l_result || ' - 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', 'JAVA SOURCE') - --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) - ) - where line > 0]'; - return l_result; - end; - - - /** - * Public functions - */ - - function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is - l_line_calls ut_coverage_helper.t_unit_line_calls; - l_result ut_coverage.t_coverage; - l_new_unit ut_coverage.t_unit_coverage; - line_no binary_integer; - l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; - l_source_object ut_coverage_helper.t_tmp_table_object; - begin - --prepare global temp table with sources - ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options)); - - l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); - loop - fetch l_source_objects_crsr - into l_source_object; - exit when l_source_objects_crsr%notfound; - - --get coverage data - l_line_calls := ut_block_helper.get_raw_coverage_data_block(l_source_object.owner, l_source_object.name); - - --if there is coverage, we need to filter out the garbage (badly indicated data) - if l_line_calls.count > 0 then - --remove lines that should not be indicted as meaningful - for i in 1 .. l_source_object.to_be_skipped_list.count loop - if l_source_object.to_be_skipped_list(i) is not null then - l_line_calls.delete(l_source_object.to_be_skipped_list(i)); - end if; - end loop; - end if; - - --if there are no file mappings or object was actually captured by profiler - if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then - - --populate total stats - l_result.total_lines := l_result.total_lines + l_source_object.lines_count; - - --populate object level coverage stats - if not l_result.objects.exists(l_source_object.full_name) then - l_result.objects(l_source_object.full_name) := l_new_unit; - l_result.objects(l_source_object.full_name).owner := l_source_object.owner; - l_result.objects(l_source_object.full_name).name := l_source_object.name; - l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count; - end if; - --map to results - line_no := l_line_calls.first; - if line_no is null then - l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count; - l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count; - else - loop - exit when line_no is null; - - --turn the block coverage into a line coverage format to allow for reading. - --whenever the linst is a part covered treat that line as a hit and execution but only part covered - - --total stats - --Get total blocks ,blocks covered, blocks not covered this will be used for PCT calc - l_result.total_blocks := nvl(l_result.total_blocks, 0) + l_line_calls(line_no).blocks; - l_result.covered_blocks := nvl(l_result.covered_blocks, 0) + l_line_calls(line_no).covered_blocks; - l_result.uncovered_blocks := nvl(l_result.uncovered_blocks, 0) + - (l_line_calls(line_no).blocks - l_line_calls(line_no).covered_blocks); - - --If line is partially covered add as part line cover and covered for line reporter - if l_line_calls(line_no).partcovered = 1 then - l_result.partcovered_lines := l_result.partcovered_lines + 1; - end if; - - if l_line_calls(line_no).covered_blocks > 0 then - l_result.covered_lines := l_result.covered_lines + 1; - end if; - - -- Use nvl as be default is null and screw the calcs - --Increase total blocks - l_result.objects(l_source_object.full_name).lines(line_no).no_blocks := l_line_calls(line_no).blocks; - l_result.objects(l_source_object.full_name).lines(line_no).covered_blocks := l_line_calls(line_no).covered_blocks; - l_result.objects(l_source_object.full_name).total_blocks := nvl(l_result.objects(l_source_object.full_name) - .total_blocks - ,0) + l_line_calls(line_no).blocks; - - --Total uncovered blocks is a line blocks minus covered blocsk - l_result.objects(l_source_object.full_name).uncovered_blocks := nvl(l_result.objects(l_source_object.full_name) - .uncovered_blocks - ,0) + - (l_line_calls(line_no).blocks - l_line_calls(line_no) - .covered_blocks); - - --If we have any covered blocks in line - if l_line_calls(line_no).covered_blocks > 0 then - --If any block is covered then we have a hit on that line - l_result.executions := l_result.executions + 1; - --object level stats - --If its part covered then mark it else treat as full cov - if l_line_calls(line_no).partcovered = 1 then - l_result.objects(l_source_object.full_name).partcovered_lines := l_result.objects(l_source_object.full_name) - .partcovered_lines + 1; - end if; - l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) - .covered_lines + 1; - - --How many blocks we covered - l_result.objects(l_source_object.full_name).covered_blocks := nvl(l_result.objects(l_source_object.full_name) - .covered_blocks - ,0) + l_line_calls(line_no) - .covered_blocks; - - --Object line executions - l_result.objects(l_source_object.full_name).executions := nvl(l_result.objects(l_source_object.full_name) - .executions - ,0) + 1; - - l_result.objects(l_source_object.full_name).lines(line_no).executions := 1; - - --Whenever there is no covered block treat as uncovered (query returns only lines where the blocks are in code so we - --dont have a false results here when there is no blocks - elsif l_line_calls(line_no).covered_blocks = 0 then - l_result.uncovered_lines := l_result.uncovered_lines + 1; - l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name) - .uncovered_lines + 1; - l_result.objects(l_source_object.full_name).lines(line_no).executions := 0; - end if; - --increase part covered counter (+ 1/0) - l_result.objects(l_source_object.full_name).lines(line_no).partcove := l_line_calls(line_no).partcovered; - line_no := l_line_calls.next(line_no); - end loop; - end if; - end if; - - end loop; - - close l_source_objects_crsr; - - return l_result; - end get_coverage_data_block; - -end; -/ diff --git a/source/core/coverage/ut_coverage_block.pks b/source/core/coverage/ut_coverage_block.pks deleted file mode 100644 index f0febb021..000000000 --- a/source/core/coverage/ut_coverage_block.pks +++ /dev/null @@ -1,22 +0,0 @@ -create or replace package ut_coverage_block authid current_user is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; - -end; -/ diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index 0f01e64fb..0b7800a27 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -16,7 +16,7 @@ create or replace package body ut_coverage_helper is limitations under the License. */ - + g_coverage_id integer; g_develop_mode boolean not null := false; g_is_started boolean not null := false; @@ -40,25 +40,10 @@ create or replace package body ut_coverage_helper is g_coverage_type := a_coverage_type; end; - procedure set_coverage_status(a_started in boolean) is - begin - g_is_started := a_started; - end; - - procedure set_develop_mode(a_develop_mode in boolean) is - begin - g_develop_mode := a_develop_mode; - end; - function get_coverage_type return varchar2 is begin return g_coverage_type; end; - - function get_coverage_id return integer is - begin - return g_coverage_id; - end; function is_develop_mode return boolean is begin @@ -66,12 +51,16 @@ create or replace package body ut_coverage_helper is end; procedure coverage_start_internal(a_run_comment varchar2,a_coverage_type in varchar2) is + l_start_block varchar2(32767):= 'call dbms_plsql_code_coverage.start_coverage(run_comment => :a_run_comment) + into :g_coverage_id'; begin set_coverage_type(a_coverage_type); - if get_coverage_type = ut_coverage.c_block_coverage then - ut_block_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); + -- Make it dynamic to allow for block coverage. + if get_coverage_type = 'block' then + execute immediate l_start_block USING IN a_run_comment, OUT g_coverage_id; + --g_coverage_id := dbms_plsql_code_coverage.start_coverage(run_comment => a_run_comment); else - ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); + dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); coverage_pause(); end if; g_is_started := true; @@ -94,33 +83,36 @@ create or replace package body ut_coverage_helper is end; procedure coverage_pause is + l_return_code binary_integer; begin if not g_develop_mode then - if get_coverage_type = ut_coverage.c_block_coverage then + if get_coverage_type = 'block' then null; else - ut_proftab_helper.coverage_pause(); + l_return_code := dbms_profiler.pause_profiler(); end if; end if; end; procedure coverage_resume is + l_return_code binary_integer; begin - if get_coverage_type = ut_coverage.c_block_coverage then + if get_coverage_type = 'block' then null; else - ut_proftab_helper.coverage_resume(); + l_return_code := dbms_profiler.resume_profiler(); end if; end; procedure coverage_stop is + l_stop_block varchar2(100) := 'call dbms_plsql_code_coverage.stop_coverage()'; begin if not g_develop_mode then g_is_started := false; - if get_coverage_type = ut_coverage.c_block_coverage then - ut_block_helper.coverage_stop(); + if get_coverage_type = 'block' then + execute immediate l_stop_block; else - ut_proftab_helper.coverage_stop(); + dbms_profiler.stop_profiler(); end if; end if; end; @@ -129,14 +121,92 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - if get_coverage_type = ut_coverage.c_block_coverage then - ut_block_helper.coverage_stop(); + if get_coverage_type = 'block' then + null; else - ut_proftab_helper.coverage_stop(); + dbms_profiler.stop_profiler(); end if; end; - procedure mock_coverage_id(a_coverage_id integer) is + function proftab_results(a_object_owner varchar2, a_object_name varchar2) return t_proftab_rows is + c_raw_coverage sys_refcursor; + l_coverage_rows t_proftab_rows; + begin + open c_raw_coverage for q'[select d.line#, + case when sum(d.total_occur) = 0 and sum(d.total_time) > 0 then 1 else sum(d.total_occur) end total_occur + from plsql_profiler_units u + join plsql_profiler_data d + on u.runid = d.runid + and u.unit_number = d.unit_number + where u.runid = :g_coverage_id + and u.unit_owner = :a_object_owner + and u.unit_name = :a_object_name + and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK') + group by d.line#]' using g_coverage_id,a_object_owner,a_object_name; + + FETCH c_raw_coverage BULK COLLECT + INTO l_coverage_rows; + CLOSE c_raw_coverage; + + RETURN l_coverage_rows; + end; + + function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is + l_tmp_data t_proftab_rows; + l_results t_unit_line_calls; + begin + l_tmp_data := proftab_results(a_object_owner => a_object_owner, a_object_name => a_object_name); + + for i in 1 .. l_tmp_data.count loop + l_results(l_tmp_data(i).line).calls := l_tmp_data(i).calls; + end loop; + return l_results; + end; + + function block_results(a_object_owner varchar2, a_object_name varchar2) return t_block_rows is + c_raw_coverage sys_refcursor; + l_coverage_rows t_block_rows; + begin + open c_raw_coverage for q'[select ccb.line + ,count(ccb.block) totalblocks + ,sum(ccb.covered) + from dbmspcc_units ccu + left outer join dbmspcc_blocks ccb + on ccu.run_id = ccb.run_id + and ccu.object_id = ccb.object_id + where ccu.run_id = :g_coverage_id + and ccu.owner = :a_object_owner + and ccu.name = :a_object_name + group by ccb.line + order by 1]' using g_coverage_id,a_object_owner,a_object_name; + + fetch c_raw_coverage bulk collect into l_coverage_rows; + close c_raw_coverage; + + return l_coverage_rows; + end; + + function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is + l_tmp_data t_block_rows; + l_results t_unit_line_calls; + + begin + l_tmp_data := block_results(a_object_owner => a_object_owner, a_object_name => a_object_name); + for i in 1 .. l_tmp_data.count loop + l_results(l_tmp_data(i).line).blocks := l_tmp_data(i).blocks; + l_results(l_tmp_data(i).line).covered_blocks := l_tmp_data(i).covered_blocks; + l_results(l_tmp_data(i).line).partcovered := case + when (l_tmp_data(i).covered_blocks > 0) and + (l_tmp_data(i).blocks > l_tmp_data(i).covered_blocks) then + 1 + else + 0 + end; + end loop; + return l_results; + end; + + procedure mock_coverage_id(a_coverage_id integer) is begin g_develop_mode := true; g_is_started := true; diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 6728fd4b3..bf6c60df8 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -17,19 +17,12 @@ create or replace package ut_coverage_helper authid definer is */ - g_coverage_id integer; g_coverage_type varchar2(32); function get_coverage_type return varchar2; - function get_coverage_id return integer; - procedure set_coverage_type(a_coverage_type in varchar2); - procedure set_coverage_status(a_started in boolean); - - procedure set_develop_mode(a_develop_mode in boolean); - --table of line calls indexed by line number --!!! this table is sparse!!! --type t_unit_line_calls is table of number(38,0) index by binary_integer; @@ -80,6 +73,10 @@ create or replace package ut_coverage_helper authid definer is procedure coverage_resume; + function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls; + + function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls; + /*** * Allows overwriting of private global variable g_coverage_id * Used internally, only for unit testing of the framework only diff --git a/source/core/coverage/ut_coverage_proftab.pkb b/source/core/coverage/ut_coverage_proftab.pkb deleted file mode 100644 index 1fa550acf..000000000 --- a/source/core/coverage/ut_coverage_proftab.pkb +++ /dev/null @@ -1,178 +0,0 @@ -create or replace package body ut_coverage_proftab is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - -- 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_cov_sources_sql(a_coverage_options ut_coverage_options) return varchar2 is - l_result varchar2(32767); - l_full_name varchar2(100); - l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_source'); - begin - if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then - l_full_name := 'f.file_name'; - else - l_full_name := 'lower(s.owner||''.''||s.name)'; - end if; - l_result := ' - select full_name, owner, name, line, to_be_skipped, text - from ( - select '||l_full_name||q'[ as full_name, - s.owner, - s.name, - s.line - - coalesce( - case when type!='TRIGGER' then 0 end, - (select min(t.line) - 1 - from ]'||l_view_name||q'[ t - where t.owner = s.owner and t.type = s.type and t.name = s.name - and regexp_like( t.text, '[A-Za-z0-9$#_]*(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, - '^([\t ]*(((not)?\s*(overriding|final|instantiable)[\t ]*)*(static|constructor|member)?[\t ]*(procedure|function)|package([\t ]+body)|begin|end([\t ]+\S+)*[ \t]*;))', 'i' - ) - then 'Y' - end as to_be_skipped - from ]'||l_view_name||q'[ s]'; - - if a_coverage_options.file_mappings is not empty then - l_result := l_result || ' - join table(:file_mappings) f - on s.name = f.object_name - and s.type = f.object_type - and s.owner = f.object_owner - where 1 = 1'; - elsif a_coverage_options.include_objects is not empty then - l_result := l_result || ' - where (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)'; - else - l_result := l_result || ' - 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', 'JAVA SOURCE') - --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) - ) - where line > 0]'; - return l_result; - end; - - /** - * Public functions - */ - function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is - l_line_calls ut_coverage_helper.t_unit_line_calls; - l_result ut_coverage.t_coverage; - l_new_unit ut_coverage.t_unit_coverage; - line_no binary_integer; - l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; - l_source_object ut_coverage_helper.t_tmp_table_object; - begin - - --prepare global temp table with sources - ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options)); - - l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); - loop - fetch l_source_objects_crsr into l_source_object; - exit when l_source_objects_crsr%notfound; - - --get coverage data - l_line_calls := ut_proftab_helper.get_raw_coverage_data_profiler( l_source_object.owner, l_source_object.name); - - --if there is coverage, we need to filter out the garbage (badly indicated data from dbms_profiler) - if l_line_calls.count > 0 then - --remove lines that should not be indicted as meaningful - for i in 1 .. l_source_object.to_be_skipped_list.count loop - if l_source_object.to_be_skipped_list(i) is not null then - l_line_calls.delete(l_source_object.to_be_skipped_list(i)); - end if; - end loop; - end if; - - --if there are no file mappings or object was actually captured by profiler - if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then - - --populate total stats - l_result.total_lines := l_result.total_lines + l_source_object.lines_count; - - --populate object level coverage stats - if not l_result.objects.exists(l_source_object.full_name) then - l_result.objects(l_source_object.full_name) := l_new_unit; - l_result.objects(l_source_object.full_name).owner := l_source_object.owner; - l_result.objects(l_source_object.full_name).name := l_source_object.name; - l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count; - end if; - --map to results - line_no := l_line_calls.first; - if line_no is null then - l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count; - l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count; - else - loop - exit when line_no is null; - - if l_line_calls(line_no).calls > 0 then - --total stats - l_result.covered_lines := l_result.covered_lines + 1; - l_result.executions := l_result.executions + l_line_calls(line_no).calls; - --object level stats - l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name).covered_lines + 1; - l_result.objects(l_source_object.full_name).executions := l_result.objects(l_source_object.full_name).executions + l_line_calls(line_no).calls; - elsif l_line_calls(line_no).calls = 0 then - l_result.uncovered_lines := l_result.uncovered_lines + 1; - l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name).uncovered_lines + 1; - end if; - l_result.objects(l_source_object.full_name).lines(line_no).executions := l_line_calls(line_no).calls; - - line_no := l_line_calls.next(line_no); - end loop; - end if; - end if; - - end loop; - - close l_source_objects_crsr; - - return l_result; - end get_coverage_data_profiler; - -end; -/ diff --git a/source/core/coverage/ut_coverage_proftab.pks b/source/core/coverage/ut_coverage_proftab.pks deleted file mode 100644 index 7f0f4ca3b..000000000 --- a/source/core/coverage/ut_coverage_proftab.pks +++ /dev/null @@ -1,22 +0,0 @@ -create or replace package ut_coverage_proftab authid current_user is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; - -end; -/ diff --git a/source/core/coverage/ut_proftab_helper.pkb b/source/core/coverage/ut_proftab_helper.pkb deleted file mode 100644 index bf40ba531..000000000 --- a/source/core/coverage/ut_proftab_helper.pkb +++ /dev/null @@ -1,93 +0,0 @@ -create or replace package body ut_proftab_helper is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - type t_proftab_row is record ( - line binary_integer, - calls number(38,0) - ); - - type t_proftab_rows is table of t_proftab_row; - - type t_block_row is record( - line binary_integer - ,blocks binary_integer - ,covered_blocks binary_integer); - - type t_block_rows is table of t_block_row; - - - procedure coverage_start(a_run_comment varchar2,a_coverage_id out integer) is - begin - dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => a_coverage_id); - end; - - procedure coverage_pause is - l_return_code binary_integer; - begin - l_return_code := dbms_profiler.pause_profiler(); - end; - - procedure coverage_resume is - l_return_code binary_integer; - begin - l_return_code := dbms_profiler.resume_profiler(); - end; - - procedure coverage_stop is - begin - dbms_profiler.stop_profiler(); - end; - - function proftab_results(a_object_owner varchar2, a_object_name varchar2) return t_proftab_rows is - c_raw_coverage sys_refcursor; - l_coverage_rows t_proftab_rows; - l_coverage_id integer := ut_coverage_helper.get_coverage_id; - begin - open c_raw_coverage for q'[select d.line#, - case when sum(d.total_occur) = 0 and sum(d.total_time) > 0 then 1 else sum(d.total_occur) end total_occur - from plsql_profiler_units u - join plsql_profiler_data d - on u.runid = d.runid - and u.unit_number = d.unit_number - where u.runid = :a_coverage_id - and u.unit_owner = :a_object_owner - and u.unit_name = :a_object_name - and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK') - group by d.line#]' using l_coverage_id,a_object_owner,a_object_name; - - FETCH c_raw_coverage BULK COLLECT - INTO l_coverage_rows; - CLOSE c_raw_coverage; - - RETURN l_coverage_rows; - end; - - function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls is - l_tmp_data t_proftab_rows; - l_results ut_coverage_helper.t_unit_line_calls; - begin - l_tmp_data := proftab_results(a_object_owner => a_object_owner, a_object_name => a_object_name); - - for i in 1 .. l_tmp_data.count loop - l_results(l_tmp_data(i).line).calls := l_tmp_data(i).calls; - end loop; - return l_results; - end; - -end; -/ diff --git a/source/core/coverage/ut_proftab_helper.pks b/source/core/coverage/ut_proftab_helper.pks deleted file mode 100644 index 53a78dbc5..000000000 --- a/source/core/coverage/ut_proftab_helper.pks +++ /dev/null @@ -1,30 +0,0 @@ -create or replace package ut_proftab_helper authid definer is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - procedure coverage_start(a_run_comment in varchar2,a_coverage_id out integer); - - procedure coverage_stop; - - procedure coverage_pause; - - procedure coverage_resume; - - function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls; - -end; -/ diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index 5bdf26fb5..ea9f71e9f 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -34,7 +34,7 @@ create or replace type body ut_run as begin l_coverage_schema_names := coalesce(a_schema_names, get_run_schemes()); l_exclude_objects := coalesce(a_exclude_objects,ut_object_names()); - l_coverage_type := coalesce(a_coverage_type,ut_coverage.c_proftab_coverage); + l_coverage_type := coalesce(a_coverage_type,'proftab'); self.run_paths := a_run_paths; self.self_type := $$plsql_unit; diff --git a/source/install.sql b/source/install.sql index 7d5d19664..9a1b2457f 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,18 +127,10 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema --gathering coverage @@install_component.sql 'core/coverage/ut_coverage_sources_tmp.sql' @@install_component.sql 'core/coverage/ut_coverage_helper.pks' -@@install_component.sql 'core/coverage/ut_block_helper.pks' -@@install_component.sql 'core/coverage/ut_proftab_helper.pks' -@@install_component.sql 'core/coverage/ut_coverage.pks' -@@install_component.sql 'core/coverage/ut_coverage_block.pks' -@@install_component.sql 'core/coverage/ut_coverage_proftab.pks' -@@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps' @@install_component.sql 'core/coverage/ut_coverage_helper.pkb' -@@install_component.sql 'core/coverage/ut_block_helper.pkb' -@@install_component.sql 'core/coverage/ut_proftab_helper.pkb' +@@install_component.sql 'core/coverage/ut_coverage.pks' @@install_component.sql 'core/coverage/ut_coverage.pkb' -@@install_component.sql 'core/coverage/ut_coverage_block.pkb' -@@install_component.sql 'core/coverage/ut_coverage_proftab.pkb' +@@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps' @@install_component.sql 'core/coverage/ut_coverage_reporter_base.tpb' --core type bodies @@ -259,10 +251,6 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'reporters/ut_coverage_html_reporter.tps' @@install_component.sql 'reporters/ut_coverage_report_html_helper.pks' @@install_component.sql 'reporters/ut_coverage_report_html_helper.pkb' -@@install_component.sql 'reporters/ut_block_report_html_helper.pks' -@@install_component.sql 'reporters/ut_proftab_report_html_helper.pks' -@@install_component.sql 'reporters/ut_block_report_html_helper.pkb' -@@install_component.sql 'reporters/ut_proftab_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_html_reporter.tpb' @@install_component.sql 'reporters/ut_coverage_sonar_reporter.tps' @@install_component.sql 'reporters/ut_coverage_sonar_reporter.tpb' diff --git a/source/reporters/ut_block_report_html_helper.pkb b/source/reporters/ut_block_report_html_helper.pkb deleted file mode 100644 index f6485f952..000000000 --- a/source/reporters/ut_block_report_html_helper.pkb +++ /dev/null @@ -1,226 +0,0 @@ -create or replace package body ut_block_report_html_helper is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage) - return clob is - l_source_code ut_varchar2_list; - l_result clob; - - function build_details_file_content(a_object_id varchar2, a_object_full_name varchar2, a_source_code ut_varchar2_list, a_coverage_unit ut_coverage.t_unit_coverage) - return clob is - l_file_part varchar2(32767); - l_result clob; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_hits varchar2(30); - begin - dbms_lob.createtemporary(l_result, true); - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_blocks, a_coverage_unit.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); - - l_file_part := '

' || - dbms_xmlgen.convert(a_object_full_name) || '

' || '

' || l_coverage_pct || ' % lines covered

' || - '
' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'

' || l_coverage_block_pct || ' % blocks covered

'|| - '
'|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
' - ||'
    '; - ut_utils.append_to_clob(l_result, l_file_part); - - for line_no in 1 .. a_source_code.count loop - if not a_coverage_unit.lines.exists(line_no) then - l_file_part := ' -
  1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
  2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks); - - l_file_part := ' -
  3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
  4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
'; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
' || '

' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - ||'

' || '' || '
' || - a_coverage.objects.count || ' files in total.
' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '
'|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
' - ||'' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
File% coveredLinesRelevant LinesLines coveredLines missed' - ||'% blocks covered' ||'
' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - || '
'; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) - return clob is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || 'Codestin Search App' || '' || - '' || - '' || - '' || '' || '' || - '
loading
' || - ''; - - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - -end; -/ diff --git a/source/reporters/ut_block_report_html_helper.pks b/source/reporters/ut_block_report_html_helper.pks deleted file mode 100644 index 9ec514ffa..000000000 --- a/source/reporters/ut_block_report_html_helper.pks +++ /dev/null @@ -1,21 +0,0 @@ -create or replace package ut_block_report_html_helper authid current_user is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) return clob; - -end; -/ diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 601986374..2deeb6380 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -98,20 +98,269 @@ create or replace package body ut_coverage_report_html_helper is return '' || a_object_full_name || ''; end; + function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage, a_coverage_type varchar2) + return clob is + l_source_code ut_varchar2_list; + l_result clob; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + + function build_details_file_content(a_object_id varchar2, a_object_full_name varchar2, a_source_code ut_varchar2_list, a_coverage_unit ut_coverage.t_unit_coverage, a_coverage_type varchar2) + return clob is + l_file_part varchar2(32767); + l_result clob; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + l_hits varchar2(30); + begin + dbms_lob.createtemporary(l_result, true); + + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(a_coverage_unit.covered_blocks, a_coverage_unit.uncovered_blocks); + end if; + + l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); + + + --l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); + + l_file_part := '

' || + dbms_xmlgen.convert(a_object_full_name) || '

' || '

' || l_coverage_pct || ' % lines covered

' || + '
' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || case + when l_coverage_type = 'block' then + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + end || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'|| + case when l_coverage_type = 'block' then + '

' || l_coverage_block_pct || ' % blocks covered

'|| + '
'|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
' + end ||'
    '; + ut_utils.append_to_clob(l_result, l_file_part); + + for line_no in 1 .. a_source_code.count loop + if not a_coverage_unit.lines.exists(line_no) then + l_file_part := ' +
  1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
  2. '; + else + l_hits := case when l_coverage_type = 'block' then + to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks) + else + to_char(a_coverage_unit.lines(line_no).executions) + end; + + l_file_part := ' +
  3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
  4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
'; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ,l_coverage_type); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage, a_coverage_type varchar2) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + begin + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + end if; + + l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
' || '

' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + case when l_coverage_type = 'block' then + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + else + ' at ' || + '' || + executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)' + end || + '

' || '' || '
' || + a_coverage.objects.count || ' files in total.
' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || case + when l_coverage_type = 'block' then + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' + else + null + end || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + case when l_coverage_type = 'block' then + '
'|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
' + end || + '' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + end if; + + l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' + else + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || '' + end || '' || + case + when l_coverage_type = 'block' then + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
File% coveredLinesRelevant LinesLines coveredLines missed' + ||case when l_coverage_type = 'block' then + '% blocks covered' + else + 'Avg. Hits / Line' + end ||'
' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || case + when l_coverage_type = 'block' then + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + else + '' || to_char(executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + end || '
'; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + /* * public definitions */ function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null, a_coverage_type varchar2 := null) return clob is + + l_file_part varchar2(32767); l_result clob; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.c_proftab_coverage); + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); begin - if l_coverage_type = ut_coverage.c_block_coverage then - l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + if l_coverage_type = 'block' then + l_coverage_pct := coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); else - l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); end if; - + + --l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || 'Codestin Search App' || '' || + '' || + '' || + '' || '' || '' || + '
loading
' || + ''; + + ut_utils.append_to_clob(l_result, l_file_part); return l_result; end; diff --git a/source/reporters/ut_coverage_report_html_helper.pks b/source/reporters/ut_coverage_report_html_helper.pks index 48c96a53d..67faeb6a1 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -17,20 +17,6 @@ create or replace package ut_coverage_report_html_helper authid current_user is */ function get_default_html_assets_path return varchar2 deterministic; - function coverage_pct(a_covered_lines integer, a_uncovered_lines integer) return number; - - function coverage_css_class(a_covered_pct number) return varchar2; - - function line_status(a_executions in ut_coverage.t_line_executions) return varchar2; - - function link_to_source_file(a_object_full_name varchar2) return varchar2; - - function object_id(a_object_full_name varchar2) return varchar2; - - function executions_per_line(a_executions number, a_lines integer) return integer; - - function line_hits_css_class(a_line_hist number) return varchar2; - function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null, a_coverage_type varchar2 := null) return clob; end; diff --git a/source/reporters/ut_proftab_report_html_helper.pkb b/source/reporters/ut_proftab_report_html_helper.pkb deleted file mode 100644 index 118d00a1b..000000000 --- a/source/reporters/ut_proftab_report_html_helper.pkb +++ /dev/null @@ -1,210 +0,0 @@ -create or replace package body ut_proftab_report_html_helper is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage) - return clob is - l_source_code ut_varchar2_list; - l_result clob; - - function build_details_file_content(a_object_id varchar2, a_object_full_name varchar2, a_source_code ut_varchar2_list, a_coverage_unit ut_coverage.t_unit_coverage) - return clob is - l_file_part varchar2(32767); - l_result clob; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_hits varchar2(30); - begin - dbms_lob.createtemporary(l_result, true); - - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); - - l_file_part := '

' || - dbms_xmlgen.convert(a_object_full_name) || '

' || '

' || l_coverage_pct || ' % lines covered

' || - '
' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'
    '; - ut_utils.append_to_clob(l_result, l_file_part); - - for line_no in 1 .. a_source_code.count loop - if not a_coverage_unit.lines.exists(line_no) then - l_file_part := ' -
  1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
  2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).executions); - - l_file_part := ' -
  3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
  4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
'; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
' || '

' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ' at ' || - '' || - ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)

' || '' || '
' || - a_coverage.objects.count || ' files in total.
' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered'|| ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
File% coveredLinesRelevant LinesLines coveredLines missed' - ||'Avg. Hits / Line
' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - || '
'; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) - return clob is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || 'Codestin Search App' || '' || - '' || - '' || - '' || '' || '' || - '
loading
' || - ''; - - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - -end; -/ diff --git a/source/reporters/ut_proftab_report_html_helper.pks b/source/reporters/ut_proftab_report_html_helper.pks deleted file mode 100644 index 59316f9bf..000000000 --- a/source/reporters/ut_proftab_report_html_helper.pks +++ /dev/null @@ -1,21 +0,0 @@ -create or replace package ut_proftab_report_html_helper authid current_user is - /* - utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project - - Licensed under the Apache License, Version 2.0 (the "License"): - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) return clob; - -end; -/