|
| 1 | +create or replace package body ut_coverage_extended is |
| 2 | + /* |
| 3 | + utPLSQL - Version 3 |
| 4 | + Copyright 2016 - 2017 utPLSQL Project |
| 5 | + |
| 6 | + Licensed under the Apache License, Version 2.0 (the "License"): |
| 7 | + you may not use this file except in compliance with the License. |
| 8 | + You may obtain a copy of the License at |
| 9 | + |
| 10 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | + |
| 12 | + Unless required by applicable law or agreed to in writing, software |
| 13 | + distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | + See the License for the specific language governing permissions and |
| 16 | + limitations under the License. |
| 17 | + */ |
| 18 | + |
| 19 | + function get_cov_sources_sql(a_coverage_options ut_coverage_options) return varchar2 is |
| 20 | + l_result varchar2(32767); |
| 21 | + l_full_name varchar2(100); |
| 22 | + l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_source'); |
| 23 | + begin |
| 24 | + if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then |
| 25 | + l_full_name := 'f.file_name'; |
| 26 | + else |
| 27 | + l_full_name := 'lower(s.owner||''.''||s.name)'; |
| 28 | + end if; |
| 29 | + l_result := ' |
| 30 | + select full_name, owner, name, line, to_be_skipped, text |
| 31 | + from ( |
| 32 | + select '||l_full_name||q'[ as full_name, |
| 33 | + s.owner, |
| 34 | + s.name, |
| 35 | + s.line - |
| 36 | + coalesce( |
| 37 | + case when type!='TRIGGER' then 0 end, |
| 38 | + (select min(t.line) - 1 |
| 39 | + from ]'||l_view_name||q'[ t |
| 40 | + where t.owner = s.owner and t.type = s.type and t.name = s.name |
| 41 | + and regexp_like( t.text, '[A-Za-z0-9$#_]*(begin|declare|compound).*','i')) |
| 42 | + ) as line, |
| 43 | + s.text, 'N' as to_be_skipped |
| 44 | + from ]'||l_view_name||q'[ s]'; |
| 45 | + |
| 46 | + if a_coverage_options.file_mappings is not empty then |
| 47 | + l_result := l_result || ' |
| 48 | + join table(:file_mappings) f |
| 49 | + on s.name = f.object_name |
| 50 | + and s.type = f.object_type |
| 51 | + and s.owner = f.object_owner |
| 52 | + where 1 = 1'; |
| 53 | + elsif a_coverage_options.include_objects is not empty then |
| 54 | + l_result := l_result || ' |
| 55 | + where (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)'; |
| 56 | + else |
| 57 | + l_result := l_result || ' |
| 58 | + where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)'; |
| 59 | + end if; |
| 60 | + l_result := l_result || q'[ |
| 61 | + and s.type not in ('PACKAGE', 'TYPE', 'JAVA SOURCE') |
| 62 | + --Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter |
| 63 | + and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el) |
| 64 | + ) |
| 65 | + where line > 0]'; |
| 66 | + return l_result; |
| 67 | + end; |
| 68 | + |
| 69 | + |
| 70 | + /** |
| 71 | + * Public functions |
| 72 | + */ |
| 73 | + |
| 74 | + /* Function extend coverage |
| 75 | + P - profiler line result, C - coverage line result, X-result |
| 76 | + Dla ka?dej linii:X=greatest(P,nvl(C,0)) |
| 77 | + Czyli: |
| 78 | + If P is null - line is irrelevant |
| 79 | + If P or X > 0 - line is covered |
| 80 | + */ |
| 81 | + |
| 82 | + |
| 83 | + function get_extended_coverage(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is |
| 84 | + l_result ut_coverage.t_coverage; |
| 85 | + l_result_block ut_coverage.t_coverage; |
| 86 | + l_result_profiler ut_coverage.t_coverage; |
| 87 | + l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; |
| 88 | + l_source_object ut_coverage_helper.t_tmp_table_object; |
| 89 | + l_new_unit ut_coverage.t_unit_coverage; |
| 90 | + line_no binary_integer; |
| 91 | + begin |
| 92 | + l_result_block := ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); |
| 93 | + l_result_profiler:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); |
| 94 | + |
| 95 | + |
| 96 | + ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options)); |
| 97 | + |
| 98 | + l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); |
| 99 | + loop |
| 100 | + fetch l_source_objects_crsr |
| 101 | + into l_source_object; |
| 102 | + exit when l_source_objects_crsr%notfound; |
| 103 | + --check if we have a hits in any of reporters |
| 104 | + if l_result_block.total_lines > 0 or l_result_profiler.total_lines > 0 then |
| 105 | + --update total stats |
| 106 | + l_result.total_lines := nvl(l_result.total_lines,0) + l_source_object.lines_count; |
| 107 | + l_result.total_blocks := l_result_block.total_blocks; |
| 108 | + l_result.uncovered_blocks := l_result_block.uncovered_blocks; |
| 109 | + l_result.covered_blocks := l_result_block.covered_blocks; |
| 110 | + l_result.partcovered_lines := l_result_block.partcovered_lines; |
| 111 | + |
| 112 | + --populate object level coverage stats |
| 113 | + if not l_result.objects.exists(l_source_object.full_name) then |
| 114 | + l_result.objects(l_source_object.full_name) := l_new_unit; |
| 115 | + l_result.objects(l_source_object.full_name).owner := l_source_object.owner; |
| 116 | + l_result.objects(l_source_object.full_name).name := l_source_object.name; |
| 117 | + l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count; |
| 118 | + l_result.objects(l_source_object.full_name).total_blocks := l_result_block.objects(l_source_object.full_name).total_blocks; |
| 119 | + l_result.objects(l_source_object.full_name).uncovered_blocks := l_result_block.objects(l_source_object.full_name).uncovered_blocks; |
| 120 | + l_result.objects(l_source_object.full_name).covered_blocks := l_result_block.objects(l_source_object.full_name).covered_blocks; |
| 121 | + l_result.objects(l_source_object.full_name).partcovered_lines := l_result_block.objects(l_source_object.full_name).partcovered_lines; |
| 122 | + end if; |
| 123 | + |
| 124 | + line_no := coalesce(l_result_block.objects(l_source_object.full_name).lines.first, |
| 125 | + l_result_profiler.objects(l_source_object.full_name).lines.first); |
| 126 | + |
| 127 | + if line_no is null then |
| 128 | + l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count; |
| 129 | + l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count; |
| 130 | + else |
| 131 | + loop |
| 132 | + exit when line_no is null; |
| 133 | + -- object level stats |
| 134 | + |
| 135 | + -- Failing on non existing data for block objects.Check if exists and then use it |
| 136 | + l_result.objects(l_source_object.full_name).lines(line_no).executions := greatest(l_result_block.objects(l_source_object.full_name).lines(line_no).executions, |
| 137 | + l_result_profiler.objects(l_source_object.full_name).lines(line_no).executions); |
| 138 | + l_result.objects(l_source_object.full_name).lines(line_no).no_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(line_no).no_blocks,0); |
| 139 | + l_result.objects(l_source_object.full_name).lines(line_no).covered_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(line_no).covered_blocks,0); |
| 140 | + l_result.objects(l_source_object.full_name).lines(line_no).partcove := l_result_block.objects(l_source_object.full_name).lines(line_no).partcove; |
| 141 | + -- total level stats |
| 142 | + |
| 143 | + -- Recalculate total lines |
| 144 | + if l_result.objects(l_source_object.full_name).lines(line_no).executions > 0 then |
| 145 | + -- total level stats |
| 146 | + l_result.executions := l_result.executions + l_result.objects(l_source_object.full_name).lines(line_no).executions; |
| 147 | + l_result.covered_lines := l_result.covered_lines + 1; |
| 148 | + -- object level stats |
| 149 | + l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) |
| 150 | + .uncovered_lines + 1; |
| 151 | + elsif l_result.objects(l_source_object.full_name).lines(line_no).executions = 0 then |
| 152 | + -- total level stats |
| 153 | + l_result.uncovered_lines := l_result.uncovered_lines + 1; |
| 154 | + -- object level stats |
| 155 | + l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name) |
| 156 | + .uncovered_lines + 1; |
| 157 | + end if; |
| 158 | + |
| 159 | + line_no := coalesce(l_result_block.objects(l_source_object.full_name).lines.next(line_no), |
| 160 | + l_result_profiler.objects(l_source_object.full_name).lines.next(line_no)); |
| 161 | + |
| 162 | + end loop; |
| 163 | + end if; |
| 164 | + end if; |
| 165 | + |
| 166 | + end loop; |
| 167 | + close l_source_objects_crsr; |
| 168 | + return l_result; |
| 169 | + |
| 170 | + end get_extended_coverage; |
| 171 | + |
| 172 | +end; |
| 173 | +/ |
0 commit comments