-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate_test_function.py
More file actions
106 lines (84 loc) · 4.02 KB
/
Copy pathcreate_test_function.py
File metadata and controls
106 lines (84 loc) · 4.02 KB
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
import sublime
import sublime_plugin
from .name_converter import CamelcaseToSnakecaseCommand
class CreateTestFunctionCommand(sublime_plugin.TextCommand):
"""Create tests for selected functions/classes.
"""
def run(self, edit):
init_endline, _ = self.view.rowcol(self.view.size())
init_point = self.view.text_point(init_endline + 1, 0)
for sel in self.view.sel():
name = self.view.substr(sel)
test_function = (self.create_test_function_for_class(name, sel)
if self.is_class(name)
else self.create_test_function_for_function(name))
endline, _ = self.view.rowcol(self.view.size())
point = self.view.text_point(endline, 0)
self.view.insert(edit, point, test_function)
n_sels = len(self.view.sel())
self.view.sel().clear()
if n_sels == 1 and not self.is_class(name):
if name:
point = self.view.text_point(self.view.rowcol(
self.view.size())[0] - 1, 12 + len(name))
self.view.sel().add(sublime.Region(point))
else:
point = self.view.text_point(self.view.rowcol(
self.view.size())[0] - 1, 11 + len(name))
self.view.sel().add(sublime.Region(point))
self.view.sel().add(sublime.Region(self.view.text_point(
self.view.rowcol(self.view.size())[0] - 2, 9)))
else:
self.view.sel().add(sublime.Region(init_point))
self.view.show(point)
def create_test_function_for_class(self, class_name, sel):
instance_name = self._class2instance(class_name)
methods = self.list_class_methods(sel)
assertions = [' assert {}.{}'.format(instance_name, method)
+ ('' if is_property else '()')
+ '\n'
for method, is_property in methods]
return ('\ndef test_{}():\n'.format(class_name)
+ ' {} = {}()\n'.format(instance_name, class_name)
+ ''.join(assertions))
def create_test_function_for_function(self, func_name):
return ('\ndef test_{}():\n'.format(func_name)
+ ' assert {}()\n'.format(func_name))
def list_class_methods(self, class_sel):
class_line = self.view.substr(self.view.line(class_sel))
class_Indentation = self._get_class_Indentation(class_line)
following_row = self.view.rowcol(class_sel.begin())[0] + 1
property_line = ' ' * (class_Indentation + 4) + '@property'
func_prefix = ' ' * (class_Indentation + 4) + 'def '
methods = []
is_property = True
# A function should be at least two lines long
while following_row < self.view.rowcol(self.view.size())[0] - 1:
line = self.view.substr(self.view.line(
self.view.text_point(following_row, 0)))
if line == property_line:
following_row += 1
next_line = self.view.substr(self.view.line(
self.view.text_point(following_row, 0)))
if next_line.startswith(func_prefix):
func_name = next_line.lstrip(func_prefix).split('(')[0]
if not func_name.startswith('_'):
methods.append((func_name, is_property))
elif line.startswith(func_prefix):
func_name = line.lstrip(func_prefix).split('(')[0]
if not func_name.startswith('_'):
methods.append((func_name, not is_property))
following_row += 1
return methods
@staticmethod
def is_class(name):
return name[0].isupper()
@staticmethod
def _class2instance(class_name):
return CamelcaseToSnakecaseCommand.camelcase2snakecase(class_name).strip('_')
@staticmethod
def _get_class_Indentation(class_line):
Indentation = 0
while class_line[Indentation] == ' ':
Indentation += 1
return Indentation