Commits

Ned Batchelder committed 9b63ca7

Unify formatting of coverage percentages, and don't show zero or 100 as a result of rounding. Fixes #41 and #70.

Comments (0)

Files changed (10)

 ------------------------------
 
 
+Version 3.4b2
+-------------
+
+- Coverage percentages are now displayed uniformly across reporting methods.  A
+  percentage is only reported as 0% or 100% if they are truly 0 or 100, and
+  are rounded otherwise.  Fixes `issue 41` and issue 70`.
+
+.. _issue 70: http://bitbucket.org/ned/coveragepy/issue/70/text-report-and-html-report-disagree-on-coverage
+.. _issue 41: http://bitbucket.org/ned/coveragepy/issue/41/report-says-100-when-it-isnt-quite-there
+
+
 Version 3.4b1 --- 21 August 2010
 --------------------------------
 
             .replace("  ", "  ")
         )
 
-def format_pct(p):
-    """Format `p` as a percentage value for the HTML reports."""
-    return "%.0f" % p
-
 def spaceless(html):
     """Squeeze out some annoying extra space from an HTML string.
 

coverage/htmlfiles/index.html

 <div id='header'>
     <div class='content'>
         <h1>Coverage report:
-            <span class='pc_cov'>{{totals.pc_covered|format_pct}}%</span>
+            <span class='pc_cov'>{{totals.pc_covered_str}}%</span>
         </h1>
     </div>
 </div>
                 <td>{{totals.n_branches}}</td>
                 <td>{{totals.n_missing_branches}}</td>
                 {% endif %}
-                <td class='right'>{{totals.pc_covered|format_pct}}%</td>
+                <td class='right'>{{totals.pc_covered_str}}%</td>
             </tr>
         </tfoot>
         <tbody>
                 <td>{{file.nums.n_branches}}</td>
                 <td>{{file.nums.n_missing_branches}}</td>
                 {% endif %}
-                <td class='right'>{{file.nums.pc_covered|format_pct}}%</td>
+                <td class='right'>{{file.nums.pc_covered_str}}%</td>
             </tr>
             {% endfor %}
         </tbody>

coverage/htmlfiles/pyfile.html

     {# IE8 rounds line-height incorrectly, and adding this emulateIE7 line makes it right! #}
     {# http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/7684445e-f080-4d8f-8529-132763348e21 #}
     <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' />
-    <title>Coverage for {{cu.name|escape}}: {{nums.pc_covered|format_pct}}%</title>
+    <title>Coverage for {{cu.name|escape}}: {{nums.pc_covered_str}}%</title>
     <link rel='stylesheet' href='style.css' type='text/css'>
     <script type='text/javascript' src='jquery-1.3.2.min.js'></script>
     <script type='text/javascript' src='coverage_html.js'></script>
 <div id='header'>
     <div class='content'>
         <h1>Coverage for <b>{{cu.name|escape}}</b> :
-            <span class='pc_cov'>{{nums.pc_covered|format_pct}}%</span>
+            <span class='pc_cov'>{{nums.pc_covered_str}}%</span>
         </h1>
         <h2 class='stats'>
             {{nums.n_statements}} statements

coverage/results.py

         return pc_cov
     pc_covered = property(_get_pc_covered)
 
+    def _get_pc_covered_str(self):
+        """Returns the percent covered, as a string, without a percent sign.
+
+        The important thing here is that "0" only be returned when it's truly
+        zero, and "100" only be returned when it's truly 100.
+
+        """
+        pc = self.pc_covered
+        if 0 < pc < 1:
+            pc = 1.0
+        elif 99 < pc < 100:
+            pc = 99.0
+        else:
+            pc = round(pc)
+        return "%.0f" % pc
+    pc_covered_str = property(_get_pc_covered_str)
+
     def __add__(self, other):
         nums = Numbers()
         nums.n_files = self.n_files + other.n_files

coverage/summary.py

             header += " Branch BrPart"
             fmt_coverage += " %6d %6d"
         header += "  Cover"
-        fmt_coverage += " %5d%%"
+        fmt_coverage += " %5s%%"
         if self.show_missing:
             header += "   Missing"
             fmt_coverage += "   %s"
                 args = (cu.name, nums.n_statements, nums.n_missing)
                 if self.branches:
                     args += (nums.n_branches, nums.n_missing_branches)
-                args += (nums.pc_covered,)
+                args += (nums.pc_covered_str,)
                 if self.show_missing:
                     args += (analysis.missing_formatted(),)
                 outfile.write(fmt_coverage % args)
             args = ("TOTAL", total.n_statements, total.n_missing)
             if self.branches:
                 args += (total.n_branches, total.n_missing_branches)
-            args += (total.pc_covered,)
+            args += (total.pc_covered_str,)
             if self.show_missing:
                 args += ("",)
             outfile.write(fmt_coverage % args)

test/farm/run/run_xxx.py

 contains("out/stdout.txt",
         "xxx: 3 4 0 7",
         "\nxxx ",           # The reporting line for xxx
-        " 7      1    85%"  # The reporting data for xxx
+        " 7      1    86%"  # The reporting data for xxx
         )
 doesnt_contain("out/stdout.txt", "No such file or directory")
 clean("out")

test/test_coverage.py

                 y = 5
             assert x == 3
             """,
-            [1,2,3,4,5,6], "4-5", report="6 2 66% 4-5")
+            [1,2,3,4,5,6], "4-5", report="6 2 67% 4-5")
         self.check_coverage("""\
             a = 1; b = 2; c = 3;
             if a != 1:

test/test_results.py

         self.assertEqual(n3.n_executed, 182)
         self.assertEqual(n3.n_missing, 28)
         self.assertAlmostEqual(n3.pc_covered, 86.666666666)
+
+    def test_pc_covered_str(self):
+        n0 = Numbers(n_files=1, n_statements=1000, n_missing=0)
+        n1 = Numbers(n_files=1, n_statements=1000, n_missing=1)
+        n999 = Numbers(n_files=1, n_statements=1000, n_missing=999)
+        n1000 = Numbers(n_files=1, n_statements=1000, n_missing=1000)
+        self.assertEqual(n0.pc_covered_str, "100")
+        self.assertEqual(n1.pc_covered_str, "99")
+        self.assertEqual(n999.pc_covered_str, "1")
+        self.assertEqual(n1000.pc_covered_str, "0")

test/test_summary.py

         self.assertEqual(self.line_count(report), 3)
         self.assertTrue("mybranch " in report)
         self.assertEqual(self.last_line_squeezed(report),
-                                                        "mybranch 5 0 2 1 85%")
+                                                        "mybranch 5 0 2 1 86%")
 
 class SummaryTest2(CoverageTest):
     """Another bunch of summary tests."""