diff options
author | Mike Crute <mcrute@gmail.com> | 2009-11-03 14:56:00 -0500 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2009-11-03 14:56:00 -0500 |
commit | a43be0b7948d2596edcd9fe7258e81d6e31a70c8 (patch) | |
tree | fa9982ab4ba488599eb3cb61e7ea9993912c5eef | |
download | nose-machineout-a43be0b7948d2596edcd9fe7258e81d6e31a70c8.tar.bz2 nose-machineout-a43be0b7948d2596edcd9fe7258e81d6e31a70c8.tar.xz nose-machineout-a43be0b7948d2596edcd9fe7258e81d6e31a70c8.zip |
Initial import
-rw-r--r-- | PKG-INFO | 19 | ||||
-rw-r--r-- | machineout.py | 119 | ||||
-rw-r--r-- | nose_machineout.egg-info/PKG-INFO | 19 | ||||
-rw-r--r-- | nose_machineout.egg-info/SOURCES.txt | 10 | ||||
-rw-r--r-- | nose_machineout.egg-info/dependency_links.txt | 1 | ||||
-rw-r--r-- | nose_machineout.egg-info/entry_points.txt | 3 | ||||
-rw-r--r-- | nose_machineout.egg-info/not-zip-safe | 1 | ||||
-rw-r--r-- | nose_machineout.egg-info/requires.txt | 1 | ||||
-rw-r--r-- | nose_machineout.egg-info/top_level.txt | 2 | ||||
-rw-r--r-- | setup.cfg | 5 | ||||
-rw-r--r-- | setup.py | 34 | ||||
-rw-r--r-- | test_machineout.py | 10 |
12 files changed, 224 insertions, 0 deletions
diff --git a/PKG-INFO b/PKG-INFO new file mode 100644 index 0000000..7237e4c --- /dev/null +++ b/PKG-INFO | |||
@@ -0,0 +1,19 @@ | |||
1 | Metadata-Version: 1.0 | ||
2 | Name: nose_machineout | ||
3 | Version: 0.2 | ||
4 | Summary: Changes output of the nose testing tool into format easily parsable by machine. | ||
5 | Home-page: http://maxischenko.in.ua/blog/entries/109/nose-vim-integration | ||
6 | Author: Max Ischenko | ||
7 | Author-email: ischenko@gmail.com | ||
8 | License: BSD | ||
9 | Download-URL: http://cheeseshop.python.org/pypi/nose_machineout/0.1 | ||
10 | Description: UNKNOWN | ||
11 | Keywords: test unittest nose | ||
12 | Platform: UNKNOWN | ||
13 | Classifier: Development Status :: 4 - Beta | ||
14 | Classifier: Environment :: Console | ||
15 | Classifier: Intended Audience :: Developers | ||
16 | Classifier: License :: OSI Approved :: Python Software Foundation License | ||
17 | Classifier: Operating System :: POSIX | ||
18 | Classifier: Programming Language :: Python | ||
19 | Classifier: Topic :: Software Development | ||
diff --git a/machineout.py b/machineout.py new file mode 100644 index 0000000..c074e30 --- /dev/null +++ b/machineout.py | |||
@@ -0,0 +1,119 @@ | |||
1 | |||
2 | """ | ||
3 | Formats nose output into format easily parsable by machine. | ||
4 | |||
5 | It is intended to be use to integrate nose with your IDE such as Vim. | ||
6 | |||
7 | @author: Max Ischenko <ischenko@gmail.com> | ||
8 | """ | ||
9 | |||
10 | import re | ||
11 | import os | ||
12 | import os.path | ||
13 | import traceback | ||
14 | from nose.plugins import Plugin | ||
15 | |||
16 | __all__ = ['NoseMachineReadableOutput'] | ||
17 | |||
18 | try: | ||
19 | import doctest | ||
20 | doctest_fname = re.sub('\.py.?$', '.py', doctest.__file__) | ||
21 | del doctest | ||
22 | except ImportError: | ||
23 | doctest_fname = None | ||
24 | |||
25 | class dummystream: | ||
26 | def write(self, *arg): | ||
27 | pass | ||
28 | def writeln(self, *arg): | ||
29 | pass | ||
30 | |||
31 | def is_doctest_traceback(fname): | ||
32 | return fname == doctest_fname | ||
33 | |||
34 | class PluginError(Exception): | ||
35 | def __repr__(self): | ||
36 | s = super(PluginError, self).__repr__() | ||
37 | return s + "\nReport bugs to ischenko@gmail.com." | ||
38 | |||
39 | class NoseMachineReadableOutput(Plugin): | ||
40 | |||
41 | """ | ||
42 | Output errors and failures in a machine-readable way. | ||
43 | """ | ||
44 | |||
45 | name = 'machineout' | ||
46 | |||
47 | doctest_failure_re = re.compile('File "([^"]+)", line (\d+), in ([^\n]+)\n(.+)', | ||
48 | re.DOTALL) | ||
49 | |||
50 | def __init__(self): | ||
51 | super(NoseMachineReadableOutput, self).__init__() | ||
52 | self.basepath = os.getcwd() | ||
53 | |||
54 | def add_options(self, parser, env): | ||
55 | super(NoseMachineReadableOutput, self).add_options(parser, env) | ||
56 | parser.add_option("--machine-output", action="store_true", | ||
57 | dest="machine_output", | ||
58 | default=False, | ||
59 | help="Reports test results in easily parsable format.") | ||
60 | |||
61 | def configure(self, options, conf): | ||
62 | super(NoseMachineReadableOutput, self).configure(options, conf) | ||
63 | self.enabled = options.machine_output | ||
64 | |||
65 | def addSkip(self, test): | ||
66 | pass | ||
67 | |||
68 | def addDeprecated(self, test): | ||
69 | pass | ||
70 | |||
71 | def addError(self, test, err, capt): | ||
72 | self.addFormatted('error', err) | ||
73 | |||
74 | def addFormatted(self, etype, err): | ||
75 | exctype, value, tb = err | ||
76 | fulltb = traceback.extract_tb(tb) | ||
77 | fname, lineno, funname, msg = fulltb[-1] | ||
78 | # explicit support for doctests is needed | ||
79 | if is_doctest_traceback(fname): | ||
80 | # doctest traceback includes pre-formatted error message | ||
81 | # which we parse (in a very crude way). | ||
82 | n = value.args[0].rindex('-'*20) | ||
83 | formatted_msg = value.args[0][n+20+1:] | ||
84 | m = self.doctest_failure_re.match(formatted_msg) | ||
85 | if not m: | ||
86 | raise RuntimeError("Can't parse doctest output: %r" % value.args[0]) | ||
87 | fname, lineno, funname, msg = m.groups() | ||
88 | if '.' in funname: # strip module package name, if any | ||
89 | funname = funname.split('.')[-1] | ||
90 | lineno = int(lineno) | ||
91 | lines = msg.split('\n') | ||
92 | msg0 = lines[0] | ||
93 | else: | ||
94 | lines = traceback.format_exception_only(exctype, value) | ||
95 | lines = [line.strip('\n') for line in lines] | ||
96 | msg0 = lines[0] | ||
97 | fname = self.format_testfname(fname) | ||
98 | prefix = "%s:%d" % (fname, lineno) | ||
99 | self.stream.writeln("%s: In %s" % (fname, funname)) | ||
100 | self.stream.writeln("%s: %s: %s" % (prefix, etype, msg0)) | ||
101 | if len(lines) > 1: | ||
102 | pad = ' '*(len(etype)+1) | ||
103 | for line in lines[1:]: | ||
104 | self.stream.writeln("%s: %s %s" % (prefix, pad, line)) | ||
105 | |||
106 | def format_testfname(self, fname): | ||
107 | "Strips common path segments if any." | ||
108 | if fname.startswith(self.basepath): | ||
109 | return fname[len(self.basepath)+1:] | ||
110 | return fname | ||
111 | |||
112 | def addFailure(self, test, err, capt, tb_info): | ||
113 | self.addFormatted('fail', err) | ||
114 | |||
115 | def setOutputStream(self, stream): | ||
116 | # grab for own use | ||
117 | self.stream = stream | ||
118 | # return dummy stream to supress normal output | ||
119 | return dummystream() | ||
diff --git a/nose_machineout.egg-info/PKG-INFO b/nose_machineout.egg-info/PKG-INFO new file mode 100644 index 0000000..ffbaa44 --- /dev/null +++ b/nose_machineout.egg-info/PKG-INFO | |||
@@ -0,0 +1,19 @@ | |||
1 | Metadata-Version: 1.0 | ||
2 | Name: nose-machineout | ||
3 | Version: 0.2 | ||
4 | Summary: Changes output of the nose testing tool into format easily parsable by machine. | ||
5 | Home-page: http://maxischenko.in.ua/blog/entries/109/nose-vim-integration | ||
6 | Author: Max Ischenko | ||
7 | Author-email: ischenko@gmail.com | ||
8 | License: BSD | ||
9 | Download-URL: http://cheeseshop.python.org/pypi/nose_machineout/0.1 | ||
10 | Description: UNKNOWN | ||
11 | Keywords: test unittest nose | ||
12 | Platform: UNKNOWN | ||
13 | Classifier: Development Status :: 4 - Beta | ||
14 | Classifier: Environment :: Console | ||
15 | Classifier: Intended Audience :: Developers | ||
16 | Classifier: License :: OSI Approved :: Python Software Foundation License | ||
17 | Classifier: Operating System :: POSIX | ||
18 | Classifier: Programming Language :: Python | ||
19 | Classifier: Topic :: Software Development | ||
diff --git a/nose_machineout.egg-info/SOURCES.txt b/nose_machineout.egg-info/SOURCES.txt new file mode 100644 index 0000000..957a1d9 --- /dev/null +++ b/nose_machineout.egg-info/SOURCES.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | machineout.py | ||
2 | setup.py | ||
3 | test_machineout.py | ||
4 | nose_machineout.egg-info/PKG-INFO | ||
5 | nose_machineout.egg-info/SOURCES.txt | ||
6 | nose_machineout.egg-info/dependency_links.txt | ||
7 | nose_machineout.egg-info/entry_points.txt | ||
8 | nose_machineout.egg-info/not-zip-safe | ||
9 | nose_machineout.egg-info/requires.txt | ||
10 | nose_machineout.egg-info/top_level.txt | ||
diff --git a/nose_machineout.egg-info/dependency_links.txt b/nose_machineout.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/nose_machineout.egg-info/dependency_links.txt | |||
@@ -0,0 +1 @@ | |||
diff --git a/nose_machineout.egg-info/entry_points.txt b/nose_machineout.egg-info/entry_points.txt new file mode 100644 index 0000000..55767e3 --- /dev/null +++ b/nose_machineout.egg-info/entry_points.txt | |||
@@ -0,0 +1,3 @@ | |||
1 | [nose.plugins] | ||
2 | machineout = machineout:NoseMachineReadableOutput | ||
3 | |||
diff --git a/nose_machineout.egg-info/not-zip-safe b/nose_machineout.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/nose_machineout.egg-info/not-zip-safe | |||
@@ -0,0 +1 @@ | |||
diff --git a/nose_machineout.egg-info/requires.txt b/nose_machineout.egg-info/requires.txt new file mode 100644 index 0000000..ada25d6 --- /dev/null +++ b/nose_machineout.egg-info/requires.txt | |||
@@ -0,0 +1 @@ | |||
nose>=0.9 \ No newline at end of file | |||
diff --git a/nose_machineout.egg-info/top_level.txt b/nose_machineout.egg-info/top_level.txt new file mode 100644 index 0000000..10b2550 --- /dev/null +++ b/nose_machineout.egg-info/top_level.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | test_machineout | ||
2 | machineout | ||
diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..861a9f5 --- /dev/null +++ b/setup.cfg | |||
@@ -0,0 +1,5 @@ | |||
1 | [egg_info] | ||
2 | tag_build = | ||
3 | tag_date = 0 | ||
4 | tag_svn_revision = 0 | ||
5 | |||
diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..679bf1e --- /dev/null +++ b/setup.py | |||
@@ -0,0 +1,34 @@ | |||
1 | #from distutils import setup | ||
2 | from setuptools import setup | ||
3 | |||
4 | setup( | ||
5 | name="nose_machineout", | ||
6 | version="0.2", | ||
7 | description="""\ | ||
8 | Changes output of the nose testing tool into format easily parsable by machine.""", | ||
9 | author="Max Ischenko", | ||
10 | author_email="ischenko@gmail.com", | ||
11 | url="http://maxischenko.in.ua/blog/entries/109/nose-vim-integration", | ||
12 | download_url="http://cheeseshop.python.org/pypi/nose_machineout/0.1", | ||
13 | install_requires = [ | ||
14 | "nose>=0.9", | ||
15 | ], | ||
16 | scripts = [], | ||
17 | license="BSD", | ||
18 | zip_safe=False, | ||
19 | py_modules=['machineout', 'test_machineout'], | ||
20 | entry_points = { | ||
21 | 'nose.plugins': ['machineout = machineout:NoseMachineReadableOutput'], | ||
22 | }, | ||
23 | classifiers=[ | ||
24 | 'Development Status :: 4 - Beta', | ||
25 | 'Environment :: Console', | ||
26 | 'Intended Audience :: Developers', | ||
27 | 'License :: OSI Approved :: Python Software Foundation License', | ||
28 | 'Operating System :: POSIX', | ||
29 | 'Programming Language :: Python', | ||
30 | 'Topic :: Software Development', | ||
31 | ], | ||
32 | keywords='test unittest nose', | ||
33 | test_suite = 'nose.collector') | ||
34 | |||
diff --git a/test_machineout.py b/test_machineout.py new file mode 100644 index 0000000..3a574d3 --- /dev/null +++ b/test_machineout.py | |||
@@ -0,0 +1,10 @@ | |||
1 | |||
2 | from machineout import * | ||
3 | |||
4 | def doctest_enabled_function(): | ||
5 | """ | ||
6 | Run with nosetests -v --with-doctest --doctest-tests --machine-output | ||
7 | >>> 2 + 2 | ||
8 | 5 | ||
9 | """ | ||
10 | pass | ||