forked from guillermooo/Vintageous
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_runner.py
123 lines (95 loc) · 4.28 KB
/
test_runner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import sublime
import sublime_plugin
import os
import unittest
import contextlib
class __vi_tests_write_buffer(sublime_plugin.TextCommand):
"""Replaces the buffer's content with the specified `text`.
`text`: Text to be written to the buffer.
"""
def run(self, edit, text=''):
self.view.replace(edit, sublime.Region(0, self.view.size()), text)
class __vi_tests_erase_all(sublime_plugin.TextCommand):
"""Replaces the buffer's content with the specified `text`.
"""
def run(self, edit):
self.view.erase(edit, sublime.Region(0, self.view.size()))
class OutputPanel(object):
def __init__(self, name, file_regex='', line_regex='', base_dir=None,
word_wrap=False, line_numbers=False, gutter=False,
scroll_past_end=False,
syntax='Packages/Text/Plain text.tmLanguage',
):
self.name = name
self.window = sublime.active_window()
if not hasattr(self, 'output_view'):
# Try not to call get_output_panel until the regexes are assigned
self.output_view = self.window.create_output_panel(self.name)
# Default to the current file directory
if (not base_dir and self.window.active_view() and
self.window.active_view().file_name()):
base_dir = os.path.dirname(
self.window.active_view().file_name()
)
self.output_view.settings().set('result_file_regex', file_regex)
self.output_view.settings().set('result_line_regex', line_regex)
self.output_view.settings().set('result_base_dir', base_dir)
self.output_view.settings().set('word_wrap', word_wrap)
self.output_view.settings().set('line_numbers', line_numbers)
self.output_view.settings().set('gutter', gutter)
self.output_view.settings().set('scroll_past_end', scroll_past_end)
self.output_view.settings().set('syntax', syntax)
# Call create_output_panel a second time after assigning the above
# settings, so that it'll be picked up as a result buffer
self.window.create_output_panel(self.name)
def write(self, s):
f = lambda: self.output_view.run_command('append', {'characters': s})
sublime.set_timeout(f, 0)
def flush(self):
pass
def show(self):
self.window.run_command(
'show_panel', {'panel': 'output.' + self.name}
)
def close(self):
pass
class RunVintageousTests(sublime_plugin.WindowCommand):
'''Runs tests and displays the result.
- Do not use ST while tests are running.
@working_dir
Required. Should be the parent of the top-level directory for `tests`.
@loader_pattern
Optional. Only run tests matching this glob.
@active_file_only
Optional. Only run tests in the active file in ST. Shadows
@loader_pattern.
To use this runner conveniently, open the command palette and select one
of the `Build: Vintageous - Test *` commands.
'''
@contextlib.contextmanager
def chdir(self, path=None):
old_path = os.getcwd()
if path is not None:
assert os.path.exists(path), "'path' is invalid"
os.chdir(path)
yield
if path is not None:
os.chdir(old_path)
def run(self, **kwargs):
with self.chdir(kwargs.get('working_dir')):
p = os.path.join(os.getcwd(), 'tests')
patt = kwargs.get('loader_pattern', 'test*.py',)
# TODO(guillermooo): I can't get $file to expand in the build
# system. It should be possible to make the following code simpler
# with it.
if kwargs.get('active_file_only') is True:
patt = os.path.basename(self.window.active_view().file_name())
suite = unittest.TestLoader().discover(p, pattern=patt)
file_regex = r'^\s*File\s*"([^.].*?)",\s*line\s*(\d+),.*$'
display = OutputPanel('vintageous.tests', file_regex=file_regex)
display.show()
runner = unittest.TextTestRunner(stream=display, verbosity=1)
def run_and_display():
runner.run(suite)
display.show()
sublime.set_timeout_async(run_and_display, 0)