1
- import re
2
- import six
3
1
from specter .spec import TestEvent , DescribeEvent , DataDescribe
4
- from specter import _
5
2
from specter .reporting import AbstractConsoleReporter , AbstractSerialReporter
6
-
7
-
8
- class TestStatus ():
9
- PASS = 'passed'
10
- FAIL = 'failed'
11
- SKIP = 'skipped'
12
- INCOMPLETE = 'incomplete'
13
- ERROR = 'error'
14
-
15
-
16
- class ConsoleColors ():
17
- BLACK = 30
18
- RED = 31
19
- GREEN = 32
20
- YELLOW = 33
21
- BLUE = 34
22
- MAGENTA = 35
23
- CYAN = 36
24
- WHITE = 37
25
-
26
- # REMOVE THIS GLOBAL WHEN WE REFACTOR THIS
27
- USE_COLOR = True
3
+ from specter .reporting .utils import (
4
+ TestStatus , print_expects , print_to_screen , get_color_from_status ,
5
+ print_test_args , get_item_level , print_indent_msg , ConsoleColors )
28
6
29
7
30
8
class ConsoleReporter (AbstractConsoleReporter , AbstractSerialReporter ):
31
- """ Temporary console reporter.
32
- At least until I can get something else written.
33
- """
9
+ """ Simple BDD Style console reporter. """
34
10
35
11
def __init__ (self , output_docstrings = False , use_color = True ):
36
12
super (ConsoleReporter , self ).__init__ ()
@@ -45,28 +21,17 @@ def __init__(self, output_docstrings=False, use_color=True):
45
21
self .output_docstrings = output_docstrings
46
22
47
23
def get_name (self ):
48
- return 'Temporary Serial console reporter'
24
+ return 'Simple BDD Serial console reporter'
49
25
50
26
def process_arguments (self , args ):
51
27
if args .no_color :
52
28
self .use_color = False
53
- global USE_COLOR
54
- USE_COLOR = False
55
-
56
- def subscribe_to_describe (self , describe ):
57
- describe .add_listener (TestEvent .COMPLETE , self .event_received )
58
- describe .add_listener (DescribeEvent .START , self .start_describe )
59
-
60
- def event_received (self , evt ):
61
- test_case = evt .payload
62
- level = get_item_level (test_case )
63
- name = test_case .pretty_name
64
- if level > 0 :
65
- name = u'\u221F {0}' .format (name )
66
29
30
+ def get_test_case_status (self , test_case , name ):
67
31
status = TestStatus .FAIL
68
32
if (test_case .success
69
- and not test_case .skipped and not test_case .incomplete ):
33
+ and not test_case .skipped
34
+ and not test_case .incomplete ):
70
35
status = TestStatus .PASS
71
36
elif test_case .incomplete :
72
37
status = TestStatus .INCOMPLETE
@@ -78,24 +43,13 @@ def event_received(self, evt):
78
43
elif test_case .error :
79
44
status = TestStatus .ERROR
80
45
81
- print_test_msg (name , level , status )
82
-
83
- print_test_args (test_case .execute_kwargs , level , status )
84
-
85
- if test_case .doc and self .output_docstrings :
86
- print_indent_msg (test_case .doc , level + 1 , status )
87
-
88
- # Print error if it exists
89
- if test_case .error :
90
- for line in test_case .error :
91
- print_test_msg (line , level + 2 , TestStatus .FAIL )
92
-
93
- print_expects (test_case , level )
46
+ return status , name
94
47
95
- # Add test to totals
48
+ def add_to_totals ( self , test_case ):
96
49
self .test_total += 1
97
50
if (test_case .success
98
- and not test_case .skipped and not test_case .incomplete ):
51
+ and not test_case .skipped
52
+ and not test_case .incomplete ):
99
53
self .passed_tests += 1
100
54
elif test_case .skipped :
101
55
self .skipped_tests += 1
@@ -107,19 +61,67 @@ def event_received(self, evt):
107
61
self .failed_tests += 1
108
62
self .test_expects += len (test_case .expects )
109
63
110
- def start_describe (self , evt ):
64
+ def output_test_case_result (self , test_case , level ):
65
+ name = test_case .pretty_name
66
+ if level > 0 :
67
+ name = u'\u221F {0}' .format (name )
68
+
69
+ status , name = self .get_test_case_status (test_case , name )
70
+
71
+ self .output (name , level , status )
72
+ print_test_args (test_case .execute_kwargs , level , status ,
73
+ self .use_color )
74
+
75
+ if test_case .doc and self .output_docstrings :
76
+ print_indent_msg (test_case .doc , level + 1 , status )
77
+
78
+ # Print error if it exists
79
+ if test_case .error :
80
+ for line in test_case .error :
81
+ self .output (line , level + 2 , TestStatus .FAIL )
82
+
83
+ #if status == TestStatus.FAIL:
84
+ print_expects (test_case , level , self .use_color )
85
+
86
+ def subscribe_to_describe (self , describe ):
87
+ describe .add_listener (TestEvent .COMPLETE , self .test_complete )
88
+ describe .add_listener (DescribeEvent .START , self .start_spec )
89
+
90
+ def test_complete (self , evt ):
91
+ test_case = evt .payload
92
+ level = get_item_level (test_case )
93
+
94
+ self .output_test_case_result (test_case , level )
95
+
96
+ self .add_to_totals (test_case )
97
+
98
+ def start_spec (self , evt ):
111
99
level = get_item_level (evt .payload )
112
100
name = evt .payload .name
113
101
if level > 0 :
114
102
name = u'\u221F {0}' .format (name )
115
- print_indent_msg (name , level , color = ConsoleColors .GREEN )
103
+
104
+ # Output Spec name
105
+ color = ConsoleColors .GREEN if self .use_color else None
106
+ print_indent_msg (name , level , color = color )
107
+
108
+ # Output Docstrings if enabled
116
109
if evt .payload .doc and self .output_docstrings :
117
110
print_indent_msg (evt .payload .doc , level + 1 )
118
111
112
+ # Warn of duplicates
119
113
if isinstance (evt .payload , DataDescribe ) and evt .payload .dup_count :
114
+ color = ConsoleColors .YELLOW if self .use_color else None
120
115
print_indent_msg ('Warning: Noticed {0} duplicate data '
121
116
'set(s)' .format (evt .payload .dup_count ),
122
- level + 1 , color = ConsoleColors .YELLOW )
117
+ level + 1 , color = color )
118
+
119
+ def output (self , msg , indent , status = None ):
120
+ """ Alias for print_indent_msg with color determined by status."""
121
+ color = None
122
+ if self .use_color :
123
+ color = get_color_from_status (status )
124
+ print_indent_msg (msg , indent , color )
123
125
124
126
def print_summary (self ):
125
127
msg = """------- Summary --------
@@ -137,116 +139,10 @@ def print_summary(self):
137
139
errored = self .errored_tests )
138
140
139
141
status = TestStatus .FAIL
140
- if self .failed_tests == 0 :
142
+ if self .failed_tests == 0 and self . errored_tests == 0 :
141
143
status = TestStatus .PASS
142
144
143
- print_colored ('\n ' )
144
- print_test_msg ('-' * 24 , 0 , status )
145
- print_test_msg (msg , 0 , status )
146
- print_test_msg ('-' * 24 , 0 , status )
147
-
148
-
149
- def print_test_msg (msg , level , status = TestStatus .PASS ):
150
- color = ConsoleColors .RED
151
- if status == TestStatus .PASS :
152
- color = ConsoleColors .GREEN
153
- elif status == TestStatus .SKIP :
154
- color = ConsoleColors .YELLOW
155
- elif status == TestStatus .INCOMPLETE :
156
- color = ConsoleColors .MAGENTA
157
-
158
- print_indent_msg (msg = msg , level = level , color = color )
159
-
160
-
161
- def pretty_print_args (kwargs ):
162
- if kwargs is None :
163
- return u'None'
164
- first_seen = False
165
- parts = []
166
- for k , v in six .iteritems (kwargs ):
167
- if not first_seen :
168
- first_seen = True
169
- else :
170
- parts .append (', ' )
171
- parts .append ('{name} = {value}' .format (name = k , value = v ))
172
- return u'' .join (parts )
173
-
174
-
175
- def print_test_args (kwargs , level , status = TestStatus .PASS ):
176
- if kwargs and (status == TestStatus .ERROR or
177
- status == TestStatus .FAIL ):
178
- msg = u'' .join ([u' Parameters: ' , pretty_print_args (kwargs )])
179
- print_test_msg (msg , level , status )
180
-
181
-
182
- def print_indent_msg (msg , level = 0 , color = ConsoleColors .WHITE ):
183
- indent = u' ' * 2
184
- msg = u'{0}{1}' .format (str (indent * level ), msg )
185
- print_colored (msg = msg , color = color )
186
-
187
-
188
- def print_msg_list (msg_list , level , color = ConsoleColors .WHITE ):
189
- for msg in msg_list :
190
- print_indent_msg (msg = msg , level = level , color = color )
191
-
192
-
193
- def print_colored (msg , color = ConsoleColors .WHITE ):
194
- if USE_COLOR :
195
- msg = u'\033 [{color}m{msg}\033 [0m' .format (color = color , msg = msg )
196
-
197
- print (msg .encode ('utf-8' ))
198
-
199
-
200
- def get_item_level (item ):
201
- levels = 0
202
- parent_above = item .parent
203
- while parent_above is not None :
204
- levels += 1
205
- parent_above = parent_above .parent
206
- return levels
207
-
208
-
209
- def print_expects (test_case , level ):
210
- # Print expects
211
- for expect in test_case .expects :
212
- mark = u'\u2718 '
213
-
214
- status = TestStatus .FAIL
215
- if expect .success :
216
- status = TestStatus .PASS
217
- mark = u'\u2714 '
218
-
219
- expect_msg = u'{mark} {msg}' .format (mark = mark , msg = expect )
220
-
221
- print_test_msg (expect_msg , level + 1 , status = status )
222
-
223
- def hardcoded (param ):
224
- result = re .match ('^(\' |"|\d)' , str (param )) is not None
225
- return result
226
-
227
- def print_param (value , param , indent , prefix ):
228
- if not expect .success and not hardcoded (param ):
229
- msg_list = str (value ).splitlines () or ['' ]
230
- prefix = _ ('{0}: {1}' ).format (param or prefix , msg_list [0 ])
231
- print_indent_msg (prefix , indent )
232
- if len (msg_list ) > 1 :
233
- print_msg_list (msg_list [1 :], indent )
234
-
235
- if expect .custom_msg :
236
- print_test_msg (expect .custom_msg , level + 3 , status = status )
237
-
238
- # Print the target parameter
239
- try :
240
- print_param (expect .target , expect .target_src_param ,
241
- level + 3 , 'Target' )
242
- except :
243
- print_param ('ERROR - Couldn\' t evaluate target value' ,
244
- expect .target_src_param , level + 3 , 'Target' )
245
-
246
- # Print the expected parameter
247
- try :
248
- print_param (expect .expected , expect .expected_src_param ,
249
- level + 3 , 'Expected' )
250
- except :
251
- print_param ('ERROR - Couldn\' t evaluate expected value' ,
252
- expect .expected_src_param , level + 3 , 'Expected' )
145
+ print_to_screen ('\n ' )
146
+ self .output ('-' * 24 , 0 , status )
147
+ self .output (msg , 0 , status )
148
+ self .output ('-' * 24 , 0 , status )
0 commit comments