529
by orip
Uber-commit - replaced 'TestOOB' with 'Testoob' in most places in the project. |
1 |
# Testoob, Python Testing Out Of (The) Box
|
553
by orip
Update copyright years |
2 |
# Copyright (C) 2005-2006 The Testoob Team
|
398
by orip
moved reporting to a subpackage |
3 |
#
|
4 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5 |
# you may not use this file except in compliance with the License.
|
|
6 |
# You may obtain a copy of the License at
|
|
7 |
#
|
|
8 |
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9 |
#
|
|
10 |
# Unless required by applicable law or agreed to in writing, software
|
|
11 |
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13 |
# See the License for the specific language governing permissions and
|
|
14 |
# limitations under the License.
|
|
15 |
||
16 |
"Color text stream reporting"
|
|
17 |
||
707
by orip
Converted textstream and colored stream to use a writers class, much cleaner |
18 |
import os, sys |
19 |
||
20 |
ANSI_CODES = { |
|
21 |
"reset" : "\x1b[0m", |
|
22 |
"bold" : "\x1b[01m", |
|
23 |
"teal" : "\x1b[36;06m", |
|
24 |
"turquoise" : "\x1b[36;01m", |
|
25 |
"fuscia" : "\x1b[35;01m", |
|
26 |
"purple" : "\x1b[35;06m", |
|
27 |
"blue" : "\x1b[34;01m", |
|
28 |
"darkblue" : "\x1b[34;06m", |
|
29 |
"green" : "\x1b[32;01m", |
|
30 |
"darkgreen" : "\x1b[32;06m", |
|
31 |
"yellow" : "\x1b[33;01m", |
|
32 |
"brown" : "\x1b[33;06m", |
|
33 |
"red" : "\x1b[31;01m", |
|
34 |
}
|
|
35 |
||
718
by orip
cosmetics |
36 |
from textstream import StreamWriter |
707
by orip
Converted textstream and colored stream to use a writers class, much cleaner |
37 |
class TerminalColorWriter(StreamWriter): |
38 |
def __init__(self, stream, color): |
|
39 |
StreamWriter.__init__(self, stream) |
|
40 |
self.code = ANSI_CODES[color] |
|
41 |
self.reset = ANSI_CODES["reset"] |
|
42 |
def write(self, s): |
|
43 |
StreamWriter.write(self, self.code) |
|
44 |
StreamWriter.write(self, s) |
|
45 |
StreamWriter.write(self, self.reset) |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
46 |
def get_bgcolor(self): |
47 |
return "unknown" |
|
707
by orip
Converted textstream and colored stream to use a writers class, much cleaner |
48 |
|
49 |
||
719
by orip
Extracted common code from Windows color writers to WindowsColorBaseWriter base |
50 |
class WindowsColorBaseWriter(StreamWriter): |
51 |
"""
|
|
52 |
All Windows writers set the color without writing special control
|
|
53 |
characters, so this class is convenient.
|
|
54 |
"""
|
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
55 |
FOREGROUND_BLUE = 0x0001 # text color contains blue. |
56 |
FOREGROUND_GREEN = 0x0002 # text color contains green. |
|
57 |
FOREGROUND_RED = 0x0004 # text color contains red. |
|
58 |
FOREGROUND_INTENSITY = 0x0008 # text color is intensified. |
|
59 |
BACKGROUND_BLUE = 0x0010 # background color contains blue. |
|
60 |
BACKGROUND_GREEN = 0x0020 # background color contains green. |
|
61 |
BACKGROUND_RED = 0x0040 # background color contains red. |
|
62 |
BACKGROUND_INTENSITY = 0x0080 # background color is intensified. |
|
63 |
||
64 |
def __init__(self, stream, color): |
|
65 |
StreamWriter.__init__(self, stream) |
|
66 |
self.reset = self._get_color() |
|
67 |
self.background = self.reset & 0xf0 |
|
68 |
CODES = { |
|
69 |
"red" : self.FOREGROUND_RED | self.FOREGROUND_INTENSITY | self.background, |
|
70 |
"green" : self.FOREGROUND_GREEN | self.FOREGROUND_INTENSITY | self.background, |
|
71 |
"yellow" : self.FOREGROUND_GREEN | self.FOREGROUND_RED | self.FOREGROUND_INTENSITY | self.background, |
|
72 |
"blue" : self.FOREGROUND_BLUE | self.FOREGROUND_INTENSITY | self.background |
|
73 |
}
|
|
74 |
self.code = CODES[color] |
|
75 |
||
719
by orip
Extracted common code from Windows color writers to WindowsColorBaseWriter base |
76 |
def write(self, s): |
77 |
self._set_color(self.code) |
|
78 |
StreamWriter.write(self, s) |
|
79 |
self._set_color(self.reset) |
|
80 |
||
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
81 |
def get_bgcolor(self): |
82 |
WHITE = self.BACKGROUND_RED | self.BACKGROUND_GREEN | self.BACKGROUND_BLUE | self.BACKGROUND_INTENSITY |
|
83 |
YELLOW = self.BACKGROUND_RED | self.BACKGROUND_GREEN | self.BACKGROUND_INTENSITY |
|
84 |
if self.background in [WHITE, YELLOW]: |
|
85 |
return "light" |
|
86 |
else: |
|
87 |
return "dark" |
|
88 |
||
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
89 |
|
719
by orip
Extracted common code from Windows color writers to WindowsColorBaseWriter base |
90 |
class Win32ColorWriterWithExecutable(WindowsColorBaseWriter): |
707
by orip
Converted textstream and colored stream to use a writers class, much cleaner |
91 |
setcolor_path = os.path.join(sys.prefix, "testoob", "setcolor.exe") |
92 |
setcolor_available = os.path.isfile(setcolor_path) |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
93 |
if not setcolor_available: |
94 |
setcolor_path = os.path.join('other','setcolor.exe') |
|
95 |
setcolor_available = os.path.isfile(setcolor_path) |
|
704
by orip
Applied kichik's win32 color patch, ticket:260 |
96 |
|
719
by orip
Extracted common code from Windows color writers to WindowsColorBaseWriter base |
97 |
def _set_color(self, code): |
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
98 |
# TODO: fail in advance if setcolor.exe isn't available?
|
704
by orip
Applied kichik's win32 color patch, ticket:260 |
99 |
if self.setcolor_available: |
833
by Ori Peleg
Moving 'subprocess' import to where its needed (ipy doesn't have subprocess) |
100 |
try: |
101 |
import subprocess |
|
102 |
except ImportError: |
|
103 |
from testoob.compatibility import subprocess |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
104 |
subprocess.Popen('"%s" set %d' % (self.setcolor_path, code)).wait() |
707
by orip
Converted textstream and colored stream to use a writers class, much cleaner |
105 |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
106 |
def _get_color(self): |
107 |
if self.setcolor_available: |
|
108 |
try: |
|
109 |
import subprocess |
|
110 |
except ImportError: |
|
111 |
from testoob.compatibility import subprocess |
|
112 |
get_pipe = subprocess.Popen('"%s" get' % (self.setcolor_path), |
|
113 |
stdout=subprocess.PIPE) |
|
114 |
color_code, _ = get_pipe.communicate() |
|
115 |
return int(color_code) |
|
116 |
else: |
|
117 |
return 0x0f |
|
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
118 |
|
119 |
||
719
by orip
Extracted common code from Windows color writers to WindowsColorBaseWriter base |
120 |
class Win32ConsoleColorWriter(WindowsColorBaseWriter): |
709
by orip
Added a Win32 reporter implemented with win32console (over 75 times faster than |
121 |
def _out_handle(self): |
122 |
import win32console |
|
123 |
return win32console.GetStdHandle(win32console.STD_OUTPUT_HANDLE) |
|
124 |
out_handle = property(_out_handle) |
|
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
125 |
|
719
by orip
Extracted common code from Windows color writers to WindowsColorBaseWriter base |
126 |
def _set_color(self, code): |
127 |
self.out_handle.SetConsoleTextAttribute( code ) |
|
709
by orip
Added a Win32 reporter implemented with win32console (over 75 times faster than |
128 |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
129 |
def _get_color(self): |
130 |
return self.out_handle.GetConsoleScreenBufferInfo()['Attributes'] |
|
131 |
||
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
132 |
|
720
by orip
Initial implementation of color output on Windows using ctypes, part of |
133 |
class WindowsCtypesColorWriter(WindowsColorBaseWriter): |
134 |
# Constants from the Windows API
|
|
135 |
STD_OUTPUT_HANDLE = -11 |
|
136 |
||
137 |
def _out_handle(self): |
|
138 |
import ctypes |
|
139 |
return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE) |
|
140 |
out_handle = property(_out_handle) |
|
141 |
||
142 |
def _console_screen_buffer_info(self): |
|
143 |
# Based on IPython's winconsole.py, written by Alexander Belchenko
|
|
723
by orip
WindowsCtypesColorWriter: fixed implementation + allow to be chosen if |
144 |
import ctypes, struct |
720
by orip
Initial implementation of color output on Windows using ctypes, part of |
145 |
csbi = ctypes.create_string_buffer(22) |
146 |
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(self.out_handle, csbi) |
|
147 |
assert res |
|
148 |
||
149 |
(bufx, bufy, curx, cury, wattr, |
|
150 |
left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw) |
|
151 |
||
152 |
return { |
|
153 |
"bufx" : bufx, |
|
154 |
"bufy" : bufy, |
|
155 |
"curx" : curx, |
|
156 |
"cury" : cury, |
|
157 |
"wattr" : wattr, |
|
158 |
"left" : left, |
|
159 |
"top" : top, |
|
160 |
"right" : right, |
|
161 |
"bottom" : bottom, |
|
162 |
"maxx" : maxx, |
|
163 |
"maxy" : maxy, |
|
164 |
}
|
|
165 |
console_screen_buffer_info = property(_console_screen_buffer_info) |
|
166 |
||
167 |
def _set_color(self, code): |
|
723
by orip
WindowsCtypesColorWriter: fixed implementation + allow to be chosen if |
168 |
import ctypes |
720
by orip
Initial implementation of color output on Windows using ctypes, part of |
169 |
ctypes.windll.kernel32.SetConsoleTextAttribute(self.out_handle, code) |
170 |
||
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
171 |
def _get_color(self): |
172 |
return self.console_screen_buffer_info["wattr"] |
|
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
173 |
|
174 |
||
708
by orip
Refactored a bit - reduced duplication |
175 |
def color_writers_creator(writer_class): |
176 |
class ColorWriters: |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
177 |
def _get_warning_color(self, bgcolor): |
178 |
import options |
|
179 |
if options.bgcolor != "auto": |
|
180 |
bgcolor = options.bgcolor |
|
181 |
bg_mapping = {"dark": "yellow", "light": "blue", "unknown": "yellow" } |
|
182 |
warning_color = bg_mapping[bgcolor] |
|
848
by Ronnie van 't Westeinde
Added optional blue color for light backgrounds |
183 |
return warning_color |
184 |
||
708
by orip
Refactored a bit - reduced duplication |
185 |
def __init__(self, stream): |
186 |
self.normal = StreamWriter(stream) |
|
187 |
self.success = writer_class(stream, "green") |
|
188 |
self.failure = writer_class(stream, "red") |
|
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
189 |
bgcolor = self.success.get_bgcolor() |
190 |
self.warning = writer_class(stream, self._get_warning_color(bgcolor)) |
|
708
by orip
Refactored a bit - reduced duplication |
191 |
return ColorWriters |
192 |
||
718
by orip
cosmetics |
193 |
from textstream import TextStreamReporter |
708
by orip
Refactored a bit - reduced duplication |
194 |
def create_colored_reporter(writer_class): |
195 |
class ColoredReporter(TextStreamReporter): |
|
196 |
def __init__(self, *args, **kwargs): |
|
197 |
kwargs["create_writers"] = color_writers_creator(writer_class) |
|
198 |
TextStreamReporter.__init__(self, *args, **kwargs) |
|
199 |
return ColoredReporter |
|
200 |
||
709
by orip
Added a Win32 reporter implemented with win32console (over 75 times faster than |
201 |
def choose_color_writer(): |
724
by orip
Added option to specifically choose a color writer through an environment |
202 |
if "TESTOOB_COLOR_WRITER" in os.environ: |
849
by Ronnie van 't Westeinde
Changed setcolor.exe, and added bgcolor option |
203 |
#print "DEBUG: using", os.environ["TESTOOB_COLOR_WRITER"]
|
724
by orip
Added option to specifically choose a color writer through an environment |
204 |
return eval(os.environ["TESTOOB_COLOR_WRITER"]) |
205 |
||
709
by orip
Added a Win32 reporter implemented with win32console (over 75 times faster than |
206 |
if sys.platform != "win32": |
207 |
return TerminalColorWriter |
|
208 |
||
209 |
try: |
|
210 |
import win32console |
|
211 |
return Win32ConsoleColorWriter |
|
212 |
except ImportError: |
|
213 |
pass
|
|
214 |
||
723
by orip
WindowsCtypesColorWriter: fixed implementation + allow to be chosen if |
215 |
try: |
216 |
import ctypes |
|
217 |
return WindowsCtypesColorWriter |
|
218 |
except ImportError: |
|
219 |
pass
|
|
220 |
||
709
by orip
Added a Win32 reporter implemented with win32console (over 75 times faster than |
221 |
return Win32ColorWriterWithExecutable |
222 |
||
223 |
ColoredTextReporter = create_colored_reporter( choose_color_writer() ) |