Skip to content

Commit

Permalink
Merge 975a9e2 into 4c0d326
Browse files Browse the repository at this point in the history
  • Loading branch information
aconrad committed Jan 7, 2015
2 parents 4c0d326 + 975a9e2 commit 18bd9e0
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 28 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

* `pycobertura diff` HTML output now only includes hunks of lines that have
coverage changes and skips unchanged classes
* handle asymmetric presence of classes in the reports (regression
introduced in 0.4.0)

## 0.4.1 (2015-01-05)

Expand Down
69 changes: 50 additions & 19 deletions pycobertura/cobertura.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ def has_class(self, class_name):
# FIXME: this will lookup a list which is slow, make it O(1)
return class_name in self.classes()

def class_lines(self, class_name):
"""
Return a list for source lines of class `class_name`.
"""
with open(self.filename(class_name)) as f:
return f.readlines()

def packages(self):
"""
Return the list of available packages in the coverage report.
Expand All @@ -250,18 +257,48 @@ def diff_total_statements(self, class_name=None):
return statements2 - statements1

def diff_total_misses(self, class_name=None):
misses1 = self.cobertura1.total_misses(class_name)
if class_name is None:
misses1 = self.cobertura1.total_misses(class_name)
misses2 = self.cobertura2.total_misses(class_name)
return misses2 - misses1

if self.cobertura1.has_class(class_name):
misses1 = self.cobertura1.total_misses(class_name)
else:
misses1 = 0

misses2 = self.cobertura2.total_misses(class_name)

return misses2 - misses1

def diff_total_hits(self, class_name=None):
hits1 = self.cobertura1.total_hits(class_name)
if class_name is None:
hits1 = self.cobertura1.total_hits(class_name)
hits2 = self.cobertura2.total_hits(class_name)
return hits2 - hits1

if self.cobertura1.has_class(class_name):
hits1 = self.cobertura1.total_hits(class_name)
else:
hits1 = 0

hits2 = self.cobertura2.total_hits(class_name)

return hits2 - hits1

def diff_line_rate(self, class_name=None):
rate1 = self.cobertura1.line_rate(class_name)
if class_name is None:
rate1 = self.cobertura1.line_rate(class_name)
rate2 = self.cobertura2.line_rate(class_name)
return rate2 - rate1

if self.cobertura1.has_class(class_name):
rate1 = self.cobertura1.line_rate(class_name)
else:
rate1 = 0.0

rate2 = self.cobertura2.line_rate(class_name)

return rate2 - rate1

def class_source(self, class_name):
Expand All @@ -274,28 +311,22 @@ def class_source(self, class_name):
`source`: actual source code for line number `lineno`
`status`: True (hit), False (miss) or None (coverage unchanged)
"""
filename1 = self.cobertura1.filename(class_name)
filename2 = self.cobertura2.filename(class_name)
if self.cobertura1.has_class(class_name):
lines1 = self.cobertura1.class_lines(class_name)
line_statuses1 = dict(self.cobertura1.line_statuses(class_name))
else:
lines1 = []
line_statuses1 = {}

for filename in (filename1, filename2):
if not os.path.exists(filename):
return [(0, '%s not found' % filename, None)]
# if not os.path.exists(filename):
# return [(0, '%s not found' % filename, None)]

try:
f1 = open(filename1)
f2 = open(filename2)
lines1 = f1.readlines()
lines2 = f2.readlines()
finally:
f1.close()
f2.close()
lines2 = self.cobertura2.class_lines(class_name)
line_statuses2 = dict(self.cobertura2.line_statuses(class_name))

# Build a dict of lineno2 -> lineno1
lineno_map = reconcile_lines(lines2, lines1)

line_statuses1 = dict(self.cobertura1.line_statuses(class_name))
line_statuses2 = dict(self.cobertura2.line_statuses(class_name))

lines = []
for lineno, line in enumerate(lines2, start=1):

Expand Down
14 changes: 12 additions & 2 deletions tests/dummy.source1.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" ?>
<!DOCTYPE coverage
SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
<coverage branch-rate="0" line-rate="0.7143" timestamp="1420383528927" version="3.7.1">
<coverage branch-rate="0" line-rate="0.4167" timestamp="1420591320487" version="3.7.1">
<!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage -->
<packages>
<package branch-rate="0" complexity="0" line-rate="0.7143" name="">
<package branch-rate="0" complexity="0" line-rate="0.4167" name="">
<classes>
<class branch-rate="0" complexity="0" filename="dummy/__init__.py" line-rate="0" name="dummy/__init__">
<methods/>
Expand All @@ -27,6 +27,16 @@
<line hits="1" number="2"/>
</lines>
</class>
<class branch-rate="0" complexity="0" filename="dummy/dummy4.py" line-rate="0" name="dummy/dummy4">
<methods/>
<lines>
<line hits="0" number="1"/>
<line hits="0" number="2"/>
<line hits="0" number="4"/>
<line hits="0" number="5"/>
<line hits="0" number="6"/>
</lines>
</class>
</classes>
</package>
</packages>
Expand Down
11 changes: 9 additions & 2 deletions tests/dummy.source2.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" ?>
<!DOCTYPE coverage
SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
<coverage branch-rate="0" line-rate="0.8889" timestamp="1420383934752" version="3.7.1">
<coverage branch-rate="0" line-rate="0.7273" timestamp="1420587302161" version="3.7.1">
<!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage -->
<packages>
<package branch-rate="0" complexity="0" line-rate="0.8889" name="">
<package branch-rate="0" complexity="0" line-rate="0.7273" name="">
<classes>
<class branch-rate="0" complexity="0" filename="dummy/__init__.py" line-rate="0" name="dummy/__init__">
<methods/>
Expand All @@ -29,6 +29,13 @@
<line hits="0" number="5"/>
</lines>
</class>
<class branch-rate="0" complexity="0" filename="dummy/dummy3.py" line-rate="0" name="dummy/dummy3">
<methods/>
<lines>
<line hits="0" number="1"/>
<line hits="0" number="2"/>
</lines>
</class>
</classes>
</package>
</packages>
Expand Down
2 changes: 2 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def test_diff__format_html():
runner = CliRunner()
result = runner.invoke(diff, [
'--format', 'html',
'--source1', 'tests/dummy',
'--source2', 'tests/dummy',
'tests/dummy.with-dummy2-better-cov.xml',
'tests/dummy.with-dummy2-better-and-worse.xml',
], catch_exceptions=False)
Expand Down
18 changes: 17 additions & 1 deletion tests/test_cobertura.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ def test_class_source__sources_not_found():
'dummy/__init__': [(0, 'dummy/__init__.py not found', None)],
'dummy/dummy': [(0, 'dummy/dummy.py not found', None)],
'dummy/dummy2': [(0, 'dummy/dummy2.py not found', None)],
'dummy/dummy4': [(0, 'dummy/dummy4.py not found', None)],
}
for class_name in cobertura.classes():
assert cobertura.class_source(class_name) == expected_sources[class_name]
Expand All @@ -246,7 +247,14 @@ def test_line_statuses():
],
'dummy/dummy2': [
(1, True),
(2, True)
(2, True),
],
'dummy/dummy4': [
(1, False),
(2, False),
(4, False),
(5, False),
(6, False)
],
}
for class_name in cobertura.classes():
Expand All @@ -273,6 +281,14 @@ def test_class_source__sources_found():
(1, 'def baz():\n', True),
(2, ' pass\n', True)
],
'dummy/dummy4': [
(1, 'def barbaz():\n', False),
(2, ' pass\n', False),
(3, '\n', None),
(4, 'def foobarbaz():\n', False),
(5, ' a = 1 + 3\n', False),
(6, ' pass\n', False)
],
}
for class_name in cobertura.classes():
assert cobertura.class_source(class_name) == \
Expand Down
12 changes: 10 additions & 2 deletions tests/test_cobertura_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ def test_diff_class_source():
(4, 'def bat():\n', True),
(5, ' pass\n', False)
],
'dummy/dummy3': [
(1, 'def foobar():\n', False),
(2, ' pass\n', False)
],
}

for class_name in cobertura2.classes():
Expand All @@ -55,9 +59,10 @@ def test_diff_total_misses():
'dummy/__init__': 0,
'dummy/dummy': -2,
'dummy/dummy2': 1,
'dummy/dummy3': 2,
}

assert differ.diff_total_misses() == -1
assert differ.diff_total_misses() == -4


def test_diff_total_misses_by_class():
Expand All @@ -77,6 +82,7 @@ def test_diff_total_misses_by_class():
'dummy/__init__': 0,
'dummy/dummy': -2,
'dummy/dummy2': 1,
'dummy/dummy3': 2,
}

for class_name in cobertura2.classes():
Expand All @@ -97,7 +103,7 @@ def test_diff_line_rate():
)
differ = CoberturaDiff(cobertura1, cobertura2)

assert differ.diff_line_rate() == 0.17459999999999998
assert differ.diff_line_rate() == 0.31059999999999993


def test_diff_line_rate_by_class():
Expand All @@ -117,6 +123,7 @@ def test_diff_line_rate_by_class():
'dummy/__init__': 0,
'dummy/dummy': 0.4,
'dummy/dummy2': -0.25,
'dummy/dummy3': 0.0,
}

for class_name in cobertura2.classes():
Expand Down Expand Up @@ -157,6 +164,7 @@ def test_diff_total_hits_by_class():
'dummy/__init__': 0,
'dummy/dummy': 2,
'dummy/dummy2': 1,
'dummy/dummy3': 0,
}

for class_name in cobertura2.classes():
Expand Down
33 changes: 31 additions & 2 deletions tests/test_reporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,29 @@ def test_html_report_delta():
<td><span class="red">+5</span>
</td>
</tr>
<tr>
<td><a href="#dummy/dummy3">dummy/dummy3</a></td>
<td>+2</td>
<td>+2</td>
<td>-</td>
<td><span class="red">+1</span>, <span class="red">+2</span>
</td>
</tr>
<tr>
<td><a href="#dummy/dummy4">dummy/dummy4</a></td>
<td>-5</td>
<td>-</td>
<td>-</td>
<td>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>TOTAL</td>
<td>+2</td>
<td>-1</td>
<td>+17.46%</td>
<td>-4</td>
<td>+31.06%</td>
<td></td>
</tr>
</tfoot>
Expand Down Expand Up @@ -493,6 +509,19 @@ def test_html_report_delta():
</span><span class="noop">
</span><span class="hit">def bat():
</span><span class="miss"> pass
</span></pre>
</div>
</div>
<h4 id="dummy/dummy3">dummy/dummy3</h4>
<div class="row">
<div class="one column lineno">
<pre>1
2
</pre>
</div>
<div class="eleven columns code">
<pre><span class="miss">def foobar():
</span><span class="miss"> pass
</span></pre>
</div>
</div>
Expand Down

0 comments on commit 18bd9e0

Please sign in to comment.