-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintegration.py
214 lines (171 loc) · 6.85 KB
/
integration.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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
import json
import os
import re
from difflib import ndiff
print("hello go-echarts!")
SNAPSHOT_FOLDER = "./snapshot"
GENERATED_FOLDER = "./html"
HTML_SUFFIX = ".html"
SNAPSHOT_HTML = {}
GENERATED_HTML = {}
FUNCTION_PATTERN = r'function\s*\([^)]*\)\s*\{.*?\}'
COLOR_MASK = '__COLOR__'
NUMBER_MASK = '123456789'
CHART_ID_MASK = '__RAND__'
FUNCTION_MASK = '9999999999'
MASK_LIST = [COLOR_MASK, NUMBER_MASK, CHART_ID_MASK, FUNCTION_MASK]
# FIXME: need find a way to mask treemap function contents
IGNORE_CHARTS = ["treemap.html"]
def compare(snapshot_opt: any, generated_opt: any) -> bool:
"""
Return the result that current snapshot_opt and generated_opt options have same keys and structures or not.
Skip check numbers/data values (int), Skip check masked contents
If all data is same in List, choose one to check is faster
Allow to have same keys in dict without same sort
:param snapshot_opt:
:param generated_opt:
:return: same structure or not
"""
if snapshot_opt is None and generated_opt is None:
return True
if isinstance(snapshot_opt, int):
return isinstance(generated_opt, int)
if isinstance(snapshot_opt, str):
if is_masked_content(snapshot_opt):
return is_masked_content(generated_opt)
else:
return snapshot_opt == generated_opt
if isinstance(snapshot_opt, list):
if not isinstance(generated_opt, list):
return False
if len(snapshot_opt) != len(generated_opt):
return False
if all(x == snapshot_opt[0] for x in snapshot_opt) and all(x == generated_opt[0] for x in generated_opt):
return compare(snapshot_opt[0], generated_opt[0])
for i, value in enumerate(snapshot_opt):
same = compare(value, generated_opt[i])
if not same:
return False
return True
if isinstance(snapshot_opt, dict):
if not isinstance(generated_opt, dict):
return False
if len(snapshot_opt.keys()) != len(generated_opt.keys()):
return False
for key, val in snapshot_opt.items():
if not generated_opt.__contains__(key):
return False
# ignore data
if key == "data":
continue
same = compare(val, generated_opt.get(key))
if not same:
return False
return True
def diff(text1: str, text2: str) -> str:
"""
Show diff contents like git diff between options
:param text1:
:param text2:
:return: diff contents
"""
find_differences = ndiff(text1.splitlines(), text2.splitlines())
return '\n'.join(line for line in find_differences if line.startswith('- ') or line.startswith('+ '))
def is_masked_content(text: str) -> bool:
return text in MASK_LIST
def mask_functions(text: str) -> str:
return re.sub(FUNCTION_PATTERN, FUNCTION_MASK, text)
def mask_colors(text: str) -> str:
return re.sub(r'#[\d\w]+', COLOR_MASK, text)
def mask_numbers(text: str) -> str:
content = re.sub(r'-?\b\d+(\.\d+)?\b', NUMBER_MASK, text)
# replace inf
return re.sub(r'\binf\b', NUMBER_MASK, content)
def find_go_echarts_instance_rand_strings(text) -> list:
return re.findall(r'goecharts_(\w*)', text)
def find_all_go_echarts_instance_options(text: str) -> list:
return re.findall(r'option_' + CHART_ID_MASK + '\s*=\s*(.*)', text)
def mask_content(text: str) -> str:
text = mask_colors(text)
text = mask_numbers(text)
instance_rand_strings = find_go_echarts_instance_rand_strings(text)
# mask rand chartID
for instance_rand_str in instance_rand_strings:
text = text.replace(instance_rand_str, CHART_ID_MASK)
return mask_functions(text)
# solve float and inf on json
def parse_float(value):
try:
return NUMBER_MASK
except ValueError:
return NUMBER_MASK
def show_result(result: dict):
if len(result) > 0:
print("\nFind diff on files! plz have a check on them ! \n")
for f, diffs in result.items():
print(f"Compare files failed with {f}")
print("Find different options from generated_content to snapshot_content : \n ")
for d in diffs:
print(d)
print("\n")
print("-" * 30)
exit(1)
else:
print(f"Compare files all pass! excellent!")
for root, dirs, files in os.walk(SNAPSHOT_FOLDER):
for file in files:
if file.endswith(HTML_SUFFIX):
SNAPSHOT_HTML[file] = os.path.join(root, file)
for root, dirs, files in os.walk(GENERATED_FOLDER):
for file in files:
if file.endswith(HTML_SUFFIX):
GENERATED_HTML[file] = (os.path.join(root, file))
print(f"Get SNAPSHOT_HTML size {len(SNAPSHOT_HTML)}")
print(f"Get GENERATED_HTML size {len(GENERATED_HTML)}")
if len(SNAPSHOT_HTML) != len(GENERATED_HTML):
print("Oops! the GENERATED_HTML size is not as same as the SNAPSHOT_HTML size !")
exit(1)
"""
FAILED_RESULT = {"file": [ diff1, diff2]}
i.e.
FAILED_RESULT = {
"bar.html": [
" + color123 ...
- color ...
"
]
}
"""
FAILED_RESULT = {}
for file, snapshot_html_path in SNAPSHOT_HTML.items():
if file in IGNORE_CHARTS:
continue
with open(snapshot_html_path, 'r') as snapshot:
snapshot_content = snapshot.read()
generated_html_path = GENERATED_HTML[file]
with open(generated_html_path, 'r') as generated:
generated_content = generated.read()
print(f"current compare files: {file}")
snapshot_content_masked = mask_content(snapshot_content)
generated_content_masked = mask_content(generated_content)
snapshot_charts_options = find_all_go_echarts_instance_options(snapshot_content_masked)
generated_charts_options = find_all_go_echarts_instance_options(generated_content_masked)
diff_list = []
if len(snapshot_charts_options) != len(generated_charts_options):
print(f"current compare files: {file} is different! failed!")
FAILED_RESULT[file] = "The instances size in each html is not same"
else:
for index, snapshot_charts_option in enumerate(snapshot_charts_options):
generated_charts_option = generated_charts_options[index]
snapshot_charts_option_json = json.loads(snapshot_charts_option, parse_float=parse_float)
generated_charts_option_json = json.loads(generated_charts_option, parse_float=parse_float)
# consider compare them via json schema directly? to do
match = compare(snapshot_charts_option_json, generated_charts_option_json)
if not match:
diff_list.append(diff(snapshot_charts_option, generated_charts_option))
if not diff_list:
print(f"current compare files: {file} is same! pass!")
else:
FAILED_RESULT[file] = diff_list
print(f"current compare files: {file} is different! failed!")
show_result(FAILED_RESULT)