OLD | NEW |
| (Empty) |
1 """Various utility functions.""" | |
2 | |
3 __unittest = True | |
4 | |
5 | |
6 _MAX_LENGTH = 80 | |
7 def safe_repr(obj, short=False): | |
8 try: | |
9 result = repr(obj) | |
10 except Exception: | |
11 result = object.__repr__(obj) | |
12 if not short or len(result) < _MAX_LENGTH: | |
13 return result | |
14 return result[:_MAX_LENGTH] + ' [truncated]...' | |
15 | |
16 def safe_str(obj): | |
17 try: | |
18 return str(obj) | |
19 except Exception: | |
20 return object.__str__(obj) | |
21 | |
22 def strclass(cls): | |
23 return "%s.%s" % (cls.__module__, cls.__name__) | |
24 | |
25 def sorted_list_difference(expected, actual): | |
26 """Finds elements in only one or the other of two, sorted input lists. | |
27 | |
28 Returns a two-element tuple of lists. The first list contains those | |
29 elements in the "expected" list but not in the "actual" list, and the | |
30 second contains those elements in the "actual" list but not in the | |
31 "expected" list. Duplicate elements in either input list are ignored. | |
32 """ | |
33 i = j = 0 | |
34 missing = [] | |
35 unexpected = [] | |
36 while True: | |
37 try: | |
38 e = expected[i] | |
39 a = actual[j] | |
40 if e < a: | |
41 missing.append(e) | |
42 i += 1 | |
43 while expected[i] == e: | |
44 i += 1 | |
45 elif e > a: | |
46 unexpected.append(a) | |
47 j += 1 | |
48 while actual[j] == a: | |
49 j += 1 | |
50 else: | |
51 i += 1 | |
52 try: | |
53 while expected[i] == e: | |
54 i += 1 | |
55 finally: | |
56 j += 1 | |
57 while actual[j] == a: | |
58 j += 1 | |
59 except IndexError: | |
60 missing.extend(expected[i:]) | |
61 unexpected.extend(actual[j:]) | |
62 break | |
63 return missing, unexpected | |
64 | |
65 def unorderable_list_difference(expected, actual, ignore_duplicate=False): | |
66 """Same behavior as sorted_list_difference but | |
67 for lists of unorderable items (like dicts). | |
68 | |
69 As it does a linear search per item (remove) it | |
70 has O(n*n) performance. | |
71 """ | |
72 missing = [] | |
73 unexpected = [] | |
74 while expected: | |
75 item = expected.pop() | |
76 try: | |
77 actual.remove(item) | |
78 except ValueError: | |
79 missing.append(item) | |
80 if ignore_duplicate: | |
81 for lst in expected, actual: | |
82 try: | |
83 while True: | |
84 lst.remove(item) | |
85 except ValueError: | |
86 pass | |
87 if ignore_duplicate: | |
88 while actual: | |
89 item = actual.pop() | |
90 unexpected.append(item) | |
91 try: | |
92 while True: | |
93 actual.remove(item) | |
94 except ValueError: | |
95 pass | |
96 return missing, unexpected | |
97 | |
98 # anything left in actual is unexpected | |
99 return missing, actual | |
OLD | NEW |