eric7/DebugClients/Python/coverage/html.py

branch
eric7
changeset 9099
0e511e0e94a3
parent 8991
2fc945191992
--- a/eric7/DebugClients/Python/coverage/html.py	Tue May 24 10:22:46 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/html.py	Tue May 24 11:00:52 2022 +0200
@@ -122,6 +122,15 @@
         return file_data
 
 
+class FileToReport:
+    """A file we're considering reporting."""
+    def __init__(self, fr, analysis):
+        self.fr = fr
+        self.analysis = analysis
+        self.rootname = flat_rootname(fr.relative_filename())
+        self.html_filename = self.rootname + ".html"
+
+
 class HtmlReporter:
     """HTML reporting."""
 
@@ -165,6 +174,8 @@
         self.datagen = HtmlDataGeneration(self.coverage)
         self.totals = Numbers(precision=self.config.precision)
         self.directory_was_empty = False
+        self.first_fr = None
+        self.final_fr = None
 
         self.template_globals = {
             # Functions available in the templates.
@@ -188,7 +199,7 @@
                 'mis': 'mis show_mis',
                 'par': 'par run show_par',
                 'run': 'run',
-            }
+            },
         }
         self.pyfile_html_source = read_data("pyfile.html")
         self.source_tmpl = Templite(self.pyfile_html_source, self.template_globals)
@@ -204,9 +215,28 @@
         self.incr.read()
         self.incr.check_global_data(self.config, self.pyfile_html_source)
 
-        # Process all the files.
+        # Process all the files. For each page we need to supply a link
+        # to the next and previous page.
+        files_to_report = []
+
         for fr, analysis in get_analysis_to_report(self.coverage, morfs):
-            self.html_file(fr, analysis)
+            ftr = FileToReport(fr, analysis)
+            should = self.should_report_file(ftr)
+            if should:
+                files_to_report.append(ftr)
+            else:
+                file_be_gone(os.path.join(self.directory, ftr.html_filename))
+
+        for i, ftr in enumerate(files_to_report):
+            if i == 0:
+                prev_html = "index.html"
+            else:
+                prev_html = files_to_report[i - 1].html_filename
+            if i == len(files_to_report) - 1:
+                next_html = "index.html"
+            else:
+                next_html = files_to_report[i + 1].html_filename
+            self.write_html_file(ftr, prev_html, next_html)
 
         if not self.all_files_nums:
             raise NoDataError("No data to report.")
@@ -214,11 +244,22 @@
         self.totals = sum(self.all_files_nums)
 
         # Write the index file.
-        self.index_file()
+        if files_to_report:
+            first_html = files_to_report[0].html_filename
+            final_html = files_to_report[-1].html_filename
+        else:
+            first_html = final_html = "index.html"
+        self.index_file(first_html, final_html)
 
         self.make_local_static_report_files()
         return self.totals.n_statements and self.totals.pc_covered
 
+    def make_directory(self):
+        """Make sure our htmlcov directory exists."""
+        ensure_dir(self.directory)
+        if not os.listdir(self.directory):
+            self.directory_was_empty = True
+
     def make_local_static_report_files(self):
         """Make local instances of static files for HTML report."""
         # The files we provide must always be copied.
@@ -236,17 +277,10 @@
         if self.extra_css:
             shutil.copyfile(self.config.extra_css, os.path.join(self.directory, self.extra_css))
 
-    def html_file(self, fr, analysis):
-        """Generate an HTML file for one source file."""
-        rootname = flat_rootname(fr.relative_filename())
-        html_filename = rootname + ".html"
-        ensure_dir(self.directory)
-        if not os.listdir(self.directory):
-            self.directory_was_empty = True
-        html_path = os.path.join(self.directory, html_filename)
-
+    def should_report_file(self, ftr):
+        """Determine if we'll report this file."""
         # Get the numbers for this file.
-        nums = analysis.numbers
+        nums = ftr.analysis.numbers
         self.all_files_nums.append(nums)
 
         if self.skip_covered:
@@ -255,24 +289,28 @@
             no_missing_branches = (nums.n_partial_branches == 0)
             if no_missing_lines and no_missing_branches:
                 # If there's an existing file, remove it.
-                file_be_gone(html_path)
                 self.skipped_covered_count += 1
-                return
+                return False
 
         if self.skip_empty:
             # Don't report on empty files.
             if nums.n_statements == 0:
-                file_be_gone(html_path)
                 self.skipped_empty_count += 1
-                return
+                return False
+
+        return True
+
+    def write_html_file(self, ftr, prev_html, next_html):
+        """Generate an HTML file for one source file."""
+        self.make_directory()
 
         # Find out if the file on disk is already correct.
-        if self.incr.can_skip_file(self.data, fr, rootname):
-            self.file_summaries.append(self.incr.index_info(rootname))
+        if self.incr.can_skip_file(self.data, ftr.fr, ftr.rootname):
+            self.file_summaries.append(self.incr.index_info(ftr.rootname))
             return
 
         # Write the HTML page for this file.
-        file_data = self.datagen.data_for_file(fr, analysis)
+        file_data = self.datagen.data_for_file(ftr.fr, ftr.analysis)
         for ldata in file_data.lines:
             # Build the HTML for the line.
             html = []
@@ -292,7 +330,7 @@
                 ldata.annotate = ",   ".join(
                     f"{ldata.number} ↛ {d}"
                     for d in ldata.short_annotations
-                    )
+                )
             else:
                 ldata.annotate = None
 
@@ -306,7 +344,7 @@
                         ", ".join(
                             f"{num:d}) {ann_long}"
                             for num, ann_long in enumerate(longs, start=1)
-                            ),
+                        ),
                     )
             else:
                 ldata.annotate_long = None
@@ -316,20 +354,26 @@
                 css_classes.append(self.template_globals['category'][ldata.category])
             ldata.css_class = ' '.join(css_classes) or "pln"
 
-        html = self.source_tmpl.render(file_data.__dict__)
+        html_path = os.path.join(self.directory, ftr.html_filename)
+        html = self.source_tmpl.render({
+            **file_data.__dict__,
+            'prev_html': prev_html,
+            'next_html': next_html,
+        })
         write_html(html_path, html)
 
         # Save this file's information for the index file.
         index_info = {
-            'nums': nums,
-            'html_filename': html_filename,
-            'relative_filename': fr.relative_filename(),
+            'nums': ftr.analysis.numbers,
+            'html_filename': ftr.html_filename,
+            'relative_filename': ftr.fr.relative_filename(),
         }
         self.file_summaries.append(index_info)
-        self.incr.set_index_info(rootname, index_info)
+        self.incr.set_index_info(ftr.rootname, index_info)
 
-    def index_file(self):
+    def index_file(self, first_html, final_html):
         """Write the index.html file for this report."""
+        self.make_directory()
         index_tmpl = Templite(read_data("index.html"), self.template_globals)
 
         skipped_covered_msg = skipped_empty_msg = ""
@@ -345,6 +389,8 @@
             'totals': self.totals,
             'skipped_covered_msg': skipped_covered_msg,
             'skipped_empty_msg': skipped_empty_msg,
+            'first_html': first_html,
+            'final_html': final_html,
         })
 
         index_file = os.path.join(self.directory, "index.html")

eric ide

mercurial