-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 24dd42d
Showing
8 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[ | ||
{ "keys": ["super+shift+c"], "command": "show_python_coverage"} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"target": "nose_exec", | ||
"cmd": ["python", "/Users/davidg/Library/Application Support/Sublime Text 2/Packages/Coverage/SublimeCoverage/nose_runner.py", "$file"], | ||
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", | ||
"selector": "source.python" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Sublime Text 2 plugin to perform code coverage analysis and highlight uncovered lines. (Work in progress.) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
from subprocess import Popen, PIPE | ||
import os | ||
import sublime, sublime_plugin | ||
import sys | ||
from SublimePythonCoverage.utils import find, find_cmd | ||
|
||
|
||
PLUGIN_FILE = os.path.abspath(__file__) | ||
|
||
|
||
class SublimePythonCoverageListener(sublime_plugin.EventListener): | ||
"""Event listener to highlight uncovered lines when a Python file is loaded.""" | ||
|
||
def on_load(self, view): | ||
if 'source.python' not in view.scope_name(0): | ||
return | ||
|
||
view.run_command('show_python_coverage') | ||
|
||
|
||
class ShowPythonCoverageCommand(sublime_plugin.TextCommand): | ||
"""Highlight uncovered lines in the current file based on a previous coverage run.""" | ||
|
||
def run(self, edit): | ||
view = self.view | ||
fname = view.file_name() | ||
if not fname: | ||
return | ||
|
||
cov_file = find(fname, '.coverage') | ||
if not cov_file: | ||
print 'Could not find .coverage file.' | ||
return | ||
|
||
python = find_cmd(PLUGIN_FILE, 'python') | ||
reader = find(PLUGIN_FILE, ('SublimePythonCoverage', 'read_coverage.py')) | ||
p = Popen([python, reader, cov_file, fname], stdout=PIPE, stderr=PIPE) | ||
stdout, stderr = p.communicate(None) | ||
print stdout, stderr | ||
|
||
outlines = [] | ||
for line in stdout.splitlines(): | ||
line = int(line) | ||
outlines.append(view.full_line(view.text_point(line - 1, 0))) | ||
view.erase_regions('SublimePythonCoverage') | ||
view.add_regions('SublimePythonCoverage', outlines, 'comment', | ||
sublime.DRAW_EMPTY | sublime.DRAW_OUTLINED) | ||
|
||
|
||
# manually import the module containing ST2's default build command, | ||
# since it's in a module whose name is a Python keyword :-s | ||
ExecCommand = __import__('exec').ExecCommand | ||
class NoseExecCommand(ExecCommand): | ||
"""An extension of the default build system which shows coverage at the end. | ||
Used by the Python Nose build system. | ||
""" | ||
|
||
def finish(self, proc): | ||
super(NoseExecCommand, self).finish(proc) | ||
for view in self.window.views(): | ||
view.run_command('show_python_coverage') | ||
|
||
|
||
# TODO: | ||
# - move read_coverage inline if possible | ||
# - coverage egg embedded or installed via helper script | ||
# - refactor nose_runner to be part of NoseExecCommand | ||
# - instructions on installation | ||
# - documentation |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
"""Helper to run nosetests appropriately for a given file. | ||
If the file is in a Python package, nosetests is run for the package. | ||
Otherwise it is run for the file. | ||
Usage: python nose_runner.py file_under_test | ||
""" | ||
import os | ||
from subprocess import Popen | ||
import sys | ||
from utils import find_cmd, find_tests | ||
|
||
|
||
if __name__ == '__main__': | ||
fname = sys.argv[1] | ||
dirname = os.path.dirname(fname) | ||
|
||
# look for a virtualenv with nosetests | ||
nose = find_cmd(fname, 'nosetests') | ||
if nose is None: | ||
nose = find_cmd(__file__, 'nosetests') | ||
if nose is None: | ||
print 'Could not find nose.' | ||
sys.exit() | ||
|
||
testpath = find_tests(fname) | ||
if os.path.isdir(testpath): | ||
os.chdir(testpath) | ||
else: | ||
os.chdir(os.path.dirname(testpath)) | ||
p = Popen([nose, '--with-coverage', testpath]) | ||
sys.exit(p.wait()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
"""Helper to run coverage analysis and list uncovered lines. | ||
Usage: python read_coverage.py coverage_file file_under_test | ||
""" | ||
|
||
import os | ||
import sys | ||
from coverage import coverage | ||
|
||
|
||
if __name__ == '__main__': | ||
cov_file, fname = sys.argv[1:] | ||
cov = coverage(data_file=cov_file) | ||
cov_dir = os.path.dirname(cov_file) | ||
os.chdir(cov_dir) | ||
relpath = os.path.relpath(fname, cov_dir) | ||
cov.load() | ||
f, s, excluded, missing, m = cov.analysis2(relpath) | ||
for m in missing: | ||
print m |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import os | ||
|
||
|
||
def find(base, rel, access=os.R_OK): | ||
if not isinstance(rel, basestring): | ||
rel = os.path.join(*rel) | ||
while 1: | ||
path = os.path.join(base, rel) | ||
if os.access(path, access): | ||
return path | ||
base = os.path.dirname(base) | ||
if not base or base == '/': | ||
return | ||
|
||
|
||
def find_cmd(base, cmd): | ||
return find(base, ('bin', cmd), os.X_OK) | ||
|
||
|
||
def find_tests(fname): | ||
dirname = os.path.dirname(fname) | ||
init = os.path.join(dirname, '__init__.py') | ||
if not os.path.exists(init): | ||
# not a package; run tests for the file | ||
return fname | ||
|
||
setup = find(dirname, 'setup.py') | ||
if setup: | ||
# run tests for the whole distribution | ||
return os.path.dirname(setup) | ||
|
||
# run tests for the package | ||
return os.path.dirname(fname) |