-
Notifications
You must be signed in to change notification settings - Fork 2
/
testing_functions.py
executable file
·197 lines (163 loc) · 6.75 KB
/
testing_functions.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/env python3
################################################################################
#
# Crunchy Report Generator
#
# Crunch Really Useful Numbers Coded Hackishly
#
# Testing functions
#
# Copyright (c) 2000, 2022, 2023, 2024 Andy Warmack
# This file is part of Crunchy Report Generator, licensed under the MIT License.
# See the LICENSE file in the project root for more information.
################################################################################
import core
import bridge
import core_functions
def reset():
core.Testing.testing_ = [False]
core.Testing.test_filename_ = [None]
core.Testing.test_f_ = [None]
core.Testing.test_pause_ = [False]
core.Testing.test_verbose_ = [False]
core.Testing.test_pass_ = [0]
core.Testing.test_fail_ = [0]
core.Testing.debug_print_mode = True
def test_message(message, verbose = False):
if core.Testing.test_verbose_[-1] or verbose:
print(core.ANSI.FG_YELLOW + '<T> ' + message + core.ANSI.FG_DEFAULT)
def test_stop(verbose = False):
core.Testing.testing_[-1] = False
core.Testing.test_pause_[-1] = False
if core.Testing.test_f_[-1] is not None:
eof_test = core.Testing.test_f_[-1].readline()
if eof_test != '':
test_message('The test was unexpectedly interrupted.', True)
while eof_test != '':
core.Testing.test_fail_[-1] += 1
eof_test = core.Testing.test_f_[-1].readline()
core.Testing.test_f_[-1].close()
core.Testing.test_f_[-1] = None
test_message('Test stopped.', verbose)
testfile = core.Testing.test_filename_[-1]
# if there is no testfile, we have no testing statistics
if testfile is None or testfile == '':
return
# show testing statistics
total = core.Testing.test_pass_[-1] + core.Testing.test_fail_[-1]
s = 's' if total != 1 else ''
tested = str(total) + ' line' + s + ' tested: '
if core.Testing.test_pass_[-1] > 0:
passed = core.ANSI.FG_GREEN + str(core.Testing.test_pass_[-1]) + ' passed' + core.ANSI.FG_YELLOW + ' :: '
else:
passed = str(core.Testing.test_pass_[-1]) + ' passed :: '
if core.Testing.test_fail_[-1] > 0:
failed = core.ANSI.FG_RED + str(core.Testing.test_fail_[-1]) + ' failed' + core.ANSI.FG_YELLOW + ' :: '
else:
failed = str(core.Testing.test_fail_[-1]) + ' failed :: '
text_offset = 0 if total < 1000 else 2 # make room for big numbers
test_message(core_functions.rjustify(tested, 18 + text_offset) + core_functions.rjustify(passed, 24 + text_offset) + failed + testfile, True)
core.Testing.test_filename_[-1] = ''
def test_versions(ranges):
# make sure a test is running
if not core.Testing.test_filename_[-1]:
test_message(f"&test versions {ranges}:", True)
test_message(' Please start a test first.', True)
test_stop()
return
# get the version and break it down
version = core.Main.version_[1:].split('.')
num_segments = len(version)
matching = False
# break down the ranges into space-separated entries
entries = ranges.split(' ')
# examine each entry
for entry in entries:
num_matching = 0
# the initial v is optional
if entry.startswith('v'):
entry = entry[1:]
# skip if the user types two spaces in a row
if entry == '':
continue
# break down the entry into dot-separated segments
segments = entry.split('.')
# fail this entry if we find the wrong number of segments
if len(segments) != num_segments:
continue
# examine each segment
for j, segment in enumerate(segments):
# wildcard
if entry == '*' or version[j] == segment:
num_matching = num_matching + 1
# numerical ranges
else:
if '-' in segment:
dashes = segment.split('-')
first = int(dashes[0])
last = int(dashes[1])
if int(version[j]) >= first and int(version[j]) <= last:
num_matching = num_matching + 1
elif '+' in segment:
dashes = segment.split('+')
first = int(dashes[0])
if int(version[j]) >= first:
num_matching = num_matching + 1
# it matches!
if num_matching == num_segments:
matching = True
break
# if we do not find a match, stop the test
if not matching:
this_version = core.Main.version_
if this_version.startswith('v'):
this_version = this_version[1:]
test_message(f"This test was not designed for version {this_version}. Expected: {ranges}", True)
core.Testing.test_filename_[-1] = None
test_stop()
def list_vars_(class_obj, filters, fullname = False, classname = None):
# 'testing' is the longest built-in class name
class_width = 7
# 'line_parse_delimiter' is usually the longest variable name
var_width = 21
if classname is None:
classname = class_obj.__name__
if fullname:
classname = f"{class_obj.__module__}.{class_obj.__name__}"
# 'core.Testing' is the longest built-in full class name
class_width = 12
# the plugin class full name tends to be the longest
plugin_classname = f"{bridge.Plugin.my.__module__}.{bridge.Plugin.my.__name__}"
if len(plugin_classname) > len(classname):
class_width = len(plugin_classname)
class_vars = vars(class_obj)
# check for partial matches
partial_matches = []
for testing_filter in filters:
p = [cv for cv in class_vars if testing_filter in cv]
partial_matches.extend(p)
filters.extend(partial_matches)
# check for class or variable matches
for var in class_vars:
attr = getattr(class_obj, var)
# we only want our own variables
if not var.startswith('__') and not callable(attr):
# finally check for matches
if filters == [] or var in filters or classname in filters:
# prettier name
if var.endswith('_') and not fullname:
var = var[:-1]
# passed the filters
print(f"{classname.rjust(class_width)}.{var.ljust(var_width)} = {attr}")
def debug(argv, fullname = False):
if argv is not None:
filters = argv.split()
else:
filters = []
list_vars_(core.Main, filters, fullname)
list_vars_(core.Cli, filters, fullname)
list_vars_(core.Testing, filters, fullname)
list_vars_(bridge.Plugin.my, filters, fullname, 'plugin')
def debug_print(message = ''):
if core.Testing.debug_print_mode:
print(message)