|
| 1 | +create or replace package body ut_block_report_html_helper 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_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage) |
| 20 | + return clob is |
| 21 | + l_source_code ut_varchar2_list; |
| 22 | + l_result clob; |
| 23 | + |
| 24 | + 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) |
| 25 | + return clob is |
| 26 | + l_file_part varchar2(32767); |
| 27 | + l_result clob; |
| 28 | + l_coverage_pct number(5, 2); |
| 29 | + l_coverage_block_pct number(5, 2); |
| 30 | + l_hits varchar2(30); |
| 31 | + begin |
| 32 | + dbms_lob.createtemporary(l_result, true); |
| 33 | + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_blocks, a_coverage_unit.uncovered_blocks); |
| 34 | + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); |
| 35 | + |
| 36 | + l_file_part := '<div class="source_table" id="' || a_object_id || '"><div class="header"> <h3>' || |
| 37 | + dbms_xmlgen.convert(a_object_full_name) || '</h3>' || '<h4><span class="' || |
| 38 | + ut_coverage_report_html_helper.coverage_css_class(l_coverage_pct) || '">' || l_coverage_pct || ' %</span> lines covered</h4>' || |
| 39 | + '<div> <b>' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) |
| 40 | + || '</b> relevant lines. ' || '<span class="green"><b>' || a_coverage_unit.covered_lines || |
| 41 | + '</b> lines covered</span> ' || |
| 42 | + '(including <span class="yellow"><b>' || a_coverage_unit.partcovered_lines || |
| 43 | + '</b> lines partially covered</span> ' |
| 44 | + || ') and <span class="red"><b>' || a_coverage_unit.uncovered_lines || |
| 45 | + '</b> lines missed</span>'||'<h4><span class="' || |
| 46 | + ut_coverage_report_html_helper.coverage_css_class(l_coverage_block_pct) || '">' || l_coverage_block_pct || ' %</span> blocks covered</h4>'|| |
| 47 | + '<div><b>'|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||'</b> blocks in total.'|| |
| 48 | + '<span class="green"><b>'||a_coverage_unit.covered_blocks||'</b> blocks covered</span> and '|| |
| 49 | + '<span class="red"><b>' || a_coverage_unit.uncovered_blocks || '</b> blocks missed.</div>' |
| 50 | + ||'</div></div><pre><ol>'; |
| 51 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 52 | + |
| 53 | + for line_no in 1 .. a_source_code.count loop |
| 54 | + if not a_coverage_unit.lines.exists(line_no) then |
| 55 | + l_file_part := ' |
| 56 | + <li class="' || ut_coverage_report_html_helper.line_status(null) || '" data-hits="" data-linenumber="' || line_no || '"> |
| 57 | + <code class="sql">' || (dbms_xmlgen.convert(a_source_code(line_no))) || |
| 58 | + '</code></li>'; |
| 59 | + else |
| 60 | + l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| |
| 61 | + to_char(a_coverage_unit.lines(line_no).no_blocks); |
| 62 | + |
| 63 | + l_file_part := ' |
| 64 | + <li class="' || ut_coverage_report_html_helper.line_status(a_coverage_unit.lines(line_no)) || '" data-hits="' || |
| 65 | + dbms_xmlgen.convert(l_hits)|| '" data-linenumber="' || (line_no) || '">'; |
| 66 | + if a_coverage_unit.lines(line_no).executions > 0 then |
| 67 | + |
| 68 | + l_file_part := l_file_part || ' |
| 69 | + <span class="hits">' || dbms_xmlgen.convert(l_hits) || |
| 70 | + '</span>'; |
| 71 | + end if; |
| 72 | + l_file_part := l_file_part || ' |
| 73 | + <code class="sql">' || (dbms_xmlgen.convert(a_source_code(line_no))) || |
| 74 | + '</code></li>'; |
| 75 | + end if; |
| 76 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 77 | + end loop; |
| 78 | + |
| 79 | + l_file_part := '</ol></pre></div>'; |
| 80 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 81 | + return l_result; |
| 82 | + end; |
| 83 | + begin |
| 84 | + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); |
| 85 | + dbms_lob.createtemporary(l_result, true); |
| 86 | + l_result := build_details_file_content(a_object_id |
| 87 | + ,a_unit.identity |
| 88 | + ,l_source_code |
| 89 | + ,a_unit_coverage |
| 90 | + ); |
| 91 | + return l_result; |
| 92 | + end; |
| 93 | + |
| 94 | + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is |
| 95 | + l_file_part varchar2(32767); |
| 96 | + l_title varchar2(100) := 'All files'; |
| 97 | + l_coverage_pct number(5, 2); |
| 98 | + l_coverage_block_pct number(5, 2); |
| 99 | + l_result clob; |
| 100 | + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); |
| 101 | + l_unit_coverage ut_coverage.t_unit_coverage; |
| 102 | + l_unit ut_coverage.t_object_name; |
| 103 | + begin |
| 104 | + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); |
| 105 | + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); |
| 106 | + |
| 107 | + dbms_lob.createtemporary(l_result, true); |
| 108 | + |
| 109 | + l_file_part := '<div class="file_list_container" id="' || l_id || '">' || '<h2><span class="group_name">' || l_title || |
| 110 | + '</span>' || ' (<span class="covered_percent"><span class="' || ut_coverage_report_html_helper.coverage_css_class(l_coverage_pct) || '">' || |
| 111 | + l_coverage_pct || '%</span></span>' || ' lines covered'|| |
| 112 | + ', <span class="covered_percent"><span class="' || ut_coverage_report_html_helper.coverage_css_class(l_coverage_block_pct) || '">' || |
| 113 | + l_coverage_block_pct || '%</span></span>' || ' executed blocks covered)' |
| 114 | + ||'</h2>' || '<a name="' || l_id || '"></a>' || '<div><b>' || |
| 115 | + a_coverage.objects.count || '</b> files in total. </div><div>' || '<b>' || |
| 116 | + (a_coverage.uncovered_lines + a_coverage.covered_lines) |
| 117 | + || '</b> relevant lines. ' || '<span class="green"><b>' || a_coverage.covered_lines || |
| 118 | + '</b> lines covered</span>' || |
| 119 | + ' (inlcluding <span class="yellow"><b>' || a_coverage.partcovered_lines || |
| 120 | + '</b> lines partially covered</span>' || ') and <span class="red"><b>' || a_coverage.uncovered_lines || '</b> lines missed.</span>'|| |
| 121 | + '<div><b>'|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||'</b> exectuted blocks in total. '|| |
| 122 | + '<span class="green"><b>'||a_coverage.covered_blocks||'</b> blocks covered</span> and '|| |
| 123 | + '<span class="red"><b>' || a_coverage.uncovered_blocks || '</b> blocks missed.</div>' |
| 124 | + ||'<table class="file_list"><thead>' || '<tr>' || |
| 125 | + '<th>File</th><th>% covered</th><th>Lines</th><th>Relevant Lines</th><th>Lines covered</th><th>Lines missed</th><th>' |
| 126 | + ||'% blocks covered' ||'</th>' || |
| 127 | + '</tr></thead><tbody>'; |
| 128 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 129 | + l_unit := a_coverage.objects.first; |
| 130 | + loop |
| 131 | + exit when l_unit is null; |
| 132 | + l_unit_coverage := a_coverage.objects(l_unit); |
| 133 | + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); |
| 134 | + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); |
| 135 | + |
| 136 | + |
| 137 | + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); |
| 138 | + |
| 139 | + l_file_part := chr(10) || '<tr>' || '<td class="strong">' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || |
| 140 | + '</td>' || '<td class="' || ut_coverage_report_html_helper.coverage_css_class(l_coverage_pct) || ' strong">' || l_coverage_pct || |
| 141 | + ' %</td>' || '<td>' || l_unit_coverage.total_lines || '</td>' || '<td>' || |
| 142 | + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || |
| 143 | + '</td>' || '<td>' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || |
| 144 | + '</td>' || '<td>' || l_unit_coverage.uncovered_lines || '</td>' || |
| 145 | + '<td class="' || ut_coverage_report_html_helper.coverage_css_class(l_coverage_block_pct) || ' strong">' ||to_char(l_coverage_block_pct)||'%' |
| 146 | + || '</td></tr>'; |
| 147 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 148 | + l_unit := a_coverage.objects.next(l_unit); |
| 149 | + end loop; |
| 150 | + l_file_part := '</tbody></table></div>'; |
| 151 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 152 | + return l_result; |
| 153 | + end; |
| 154 | + |
| 155 | + /* |
| 156 | + * public definitions |
| 157 | + */ |
| 158 | + function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) |
| 159 | + return clob is |
| 160 | + |
| 161 | + l_file_part varchar2(32767); |
| 162 | + l_result clob; |
| 163 | + l_title varchar2(250); |
| 164 | + l_coverage_pct number(5, 2); |
| 165 | + l_time_str varchar2(50); |
| 166 | + l_using varchar2(1000); |
| 167 | + l_unit ut_coverage.t_full_name; |
| 168 | + begin |
| 169 | + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); |
| 170 | + l_time_str := ut_utils.to_string(sysdate); |
| 171 | + l_using := case |
| 172 | + when a_command_line is not null then |
| 173 | + '<br/>using ' || dbms_xmlgen.convert(a_command_line) |
| 174 | + end; |
| 175 | + dbms_lob.createtemporary(l_result, true); |
| 176 | + |
| 177 | + l_title := case |
| 178 | + when a_project_name is null then |
| 179 | + 'Code coverage' |
| 180 | + else |
| 181 | + dbms_xmlgen.convert(a_project_name) || ' code coverage' |
| 182 | + end; |
| 183 | + --TODO - build main file containing total run data and per schema data |
| 184 | + l_file_part := '<!DOCTYPE html><html xmlns=''http://www.w3.org/1999/xhtml''><head>' || '<title>' || l_title || |
| 185 | + '</title>' || '<meta http-equiv="content-type" content="text/html; charset=utf-8" />' || |
| 186 | + '<script src=''' || a_assets_path || 'application.js'' type=''text/javascript''></script>' || |
| 187 | + '<link href=''' || a_assets_path || |
| 188 | + 'application.css'' media=''screen, projection, print'' rel=''stylesheet'' type=''text/css''>' || |
| 189 | + '<link rel="shortcut icon" type="image/png" href="' || a_assets_path || 'favicon_' || |
| 190 | + ut_coverage_report_html_helper.coverage_css_class(l_coverage_pct) || '.png" />' || '<link rel="icon" type="image/png" href="' || |
| 191 | + a_assets_path || 'favicon_' || ut_coverage_report_html_helper.coverage_css_class(l_coverage_pct) || '.png" />' || '</head>' || |
| 192 | + '<body><div id="loading"><img src="' || a_assets_path || 'loading.gif" alt="loading"/></div>' || |
| 193 | + '<div id="wrapper" style="display:none;">' || |
| 194 | + '<div class="timestamp">Generated <abbr class="timeago" title="' || l_time_str || '">' || l_time_str || |
| 195 | + '</abbr></div>' || '<ul class="group_tabs"></ul>' || '<div id="content">'; |
| 196 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 197 | + |
| 198 | + dbms_lob.append(l_result, file_list('All files', a_coverage_data)); |
| 199 | + |
| 200 | + l_file_part := chr(10) || '</div><div id="footer">' || |
| 201 | + 'Generated by <a href="http://github.com/utPLSQL/utPLSQL">utPLSQL ' || ut_utils.gc_version || |
| 202 | + '</a><br/>' || |
| 203 | + 'Based on <a href="http://github.com/colszowka/simplecov-html">simplecov-html</a> v0.10.0 ' || |
| 204 | + l_using || '' || '</div><div class="source_files">'; |
| 205 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 206 | + |
| 207 | + l_unit := a_coverage_data.objects.first; |
| 208 | + loop |
| 209 | + exit when l_unit is null; |
| 210 | + dbms_lob.append(l_result |
| 211 | + ,get_details_file_content(ut_coverage_report_html_helper.object_id(l_unit) |
| 212 | + ,ut_object_name(a_coverage_data.objects(l_unit).owner |
| 213 | + ,a_coverage_data.objects(l_unit).name) |
| 214 | + ,a_coverage_data.objects(l_unit) |
| 215 | + )); |
| 216 | + l_unit := a_coverage_data.objects.next(l_unit); |
| 217 | + end loop; |
| 218 | + |
| 219 | + l_file_part := '</div></div></body></html>'; |
| 220 | + |
| 221 | + ut_utils.append_to_clob(l_result, l_file_part); |
| 222 | + return l_result; |
| 223 | + end; |
| 224 | + |
| 225 | +end; |
| 226 | +/ |
0 commit comments