Skip to content

Commit 59800da

Browse files
committed
Initial commit
0 parents  commit 59800da

File tree

6 files changed

+140
-0
lines changed

6 files changed

+140
-0
lines changed

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Qualified Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# CodewarsTestRunner
2+
3+
```python
4+
import unittest
5+
from codewars_unittest import CodewarsTestRunner
6+
7+
8+
unittest.main(testRunner=CodewarsTestRunner())
9+
```

codewars_unittest/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .test_runner import CodewarsTestRunner

codewars_unittest/test_result.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import unittest
2+
import traceback
3+
4+
# Use timeit.default_timer for Python 2 compatibility.
5+
# default_timer is time.perf_counter on 3.3+
6+
from timeit import default_timer as perf_counter
7+
8+
__unittest = True
9+
10+
11+
class CodewarsTestResult(unittest.TestResult):
12+
def __init__(self):
13+
# Note that we need to avoid super() and use
14+
# super(CodewarsTestResult, self) for Python 2 compatibility
15+
super(CodewarsTestResult, self).__init__()
16+
self.start = 0.0
17+
18+
def startTest(self, test):
19+
desc = test.shortDescription()
20+
if desc is None:
21+
desc = test._testMethodName
22+
print("\n<IT::>" + desc)
23+
super(CodewarsTestResult, self).startTest(test)
24+
self.start = perf_counter()
25+
26+
def stopTest(self, test):
27+
print("\n<COMPLETEDIN::>{:.4f}".format(1000 * (perf_counter() - self.start)))
28+
super(CodewarsTestResult, self).stopTest(test)
29+
30+
def addSuccess(self, test):
31+
print("\n<PASSED::>Test Passed")
32+
super(CodewarsTestResult, self).addSuccess(test)
33+
34+
def addError(self, test, err):
35+
print("\n<ERROR::>Unhandled Exception")
36+
print(
37+
"\n<LOG:ESC:Error>"
38+
+ esc("".join(traceback.format_exception_only(err[0], err[1])))
39+
)
40+
print("\n<LOG:ESC:Traceback>" + esc(self._exc_info_to_string(err, test)))
41+
super(CodewarsTestResult, self).addError(test, err)
42+
43+
def addFailure(self, test, err):
44+
print("\n<FAILED::>Test Failed")
45+
print(
46+
"\n<LOG:ESC:Failure>"
47+
+ esc("".join(traceback.format_exception_only(err[0], err[1])))
48+
)
49+
super(CodewarsTestResult, self).addFailure(test, err)
50+
51+
# from unittest/result.py
52+
def _exc_info_to_string(self, err, test):
53+
exctype, value, tb = err
54+
# Skip test runner traceback levels
55+
while tb and self._is_relevant_tb_level(tb):
56+
tb = tb.tb_next
57+
if exctype is test.failureException:
58+
length = self._count_relevant_tb_levels(
59+
tb
60+
) # Skip assert*() traceback levels
61+
else:
62+
length = None
63+
return "".join(traceback.format_tb(tb, limit=length))
64+
65+
def _is_relevant_tb_level(self, tb):
66+
return "__unittest" in tb.tb_frame.f_globals
67+
68+
def _count_relevant_tb_levels(self, tb):
69+
length = 0
70+
while tb and not self._is_relevant_tb_level(tb):
71+
length += 1
72+
tb = tb.tb_next
73+
return length
74+
75+
76+
def esc(s):
77+
return s.replace("\n", "<:LF:>")

codewars_unittest/test_runner.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Use timeit.default_timer for Python 2 compatibility.
2+
# default_timer is time.perf_counter on 3.3+
3+
from timeit import default_timer as perf_counter
4+
5+
from .test_result import CodewarsTestResult
6+
7+
8+
class CodewarsTestRunner(object):
9+
def __init__(self):
10+
pass
11+
12+
def run(self, test):
13+
r = CodewarsTestResult()
14+
s = perf_counter()
15+
print("\n<DESCRIBE::>Tests")
16+
try:
17+
test(r)
18+
finally:
19+
pass
20+
print("\n<COMPLETEDIN::>{:.4f}".format(1000 * (perf_counter() - s)))
21+
return r

setup.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name="codewars_unittest",
5+
version="0.1.0",
6+
packages=["codewars_unittest"],
7+
license="MIT",
8+
description="unittest runner with Codewars output",
9+
install_requires=[],
10+
url="https://github.com/Codewars/python-unittest",
11+
)

0 commit comments

Comments
 (0)