1import sys 2import os 3import json 4import re 5 6if sys.version_info[0] >= 3: 7 unicode = str 8 9def is_bool(x, val=None): 10 return isinstance(x, bool) and (val is None or x == val) 11 12def is_dict(x): 13 return isinstance(x, dict) 14 15def is_list(x): 16 return isinstance(x, list) 17 18def is_int(x, val=None): 19 return (isinstance(x, int) or isinstance(x, long)) and (val is None or x == val) 20 21def is_string(x, val=None): 22 return (isinstance(x, str) or isinstance(x, unicode)) and (val is None or x == val) 23 24def matches(s, pattern): 25 return is_string(s) and bool(re.search(pattern, s)) 26 27def check_list_match(match, actual, expected, check=None, check_exception=None, missing_exception=None, extra_exception=None, allow_extra=False): 28 """ 29 Handle the common pattern of making sure every actual item "matches" some 30 item in the expected list, and that neither list has extra items after 31 matching is completed. 32 33 @param match: Callback to check if an actual item matches an expected 34 item. Return True if the item matches, return False if the item doesn't 35 match. 36 @param actual: List of actual items to search. 37 @param expected: List of expected items to match. 38 @param check: Optional function to check that the actual item is valid by 39 comparing it to the expected item. 40 @param check_exception: Optional function that returns an argument to 41 append to any exception thrown by the check function. 42 @param missing_exception: Optional function that returns an argument to 43 append to the exception thrown when an item is not found. 44 @param extra_exception: Optional function that returns an argument to 45 append to the exception thrown when an extra item is found. 46 @param allow_extra: Optional parameter allowing there to be extra actual 47 items after all the expected items have been found. 48 """ 49 assert is_list(actual) 50 _actual = actual[:] 51 for expected_item in expected: 52 found = False 53 for i, actual_item in enumerate(_actual): 54 if match(actual_item, expected_item): 55 if check: 56 try: 57 check(actual_item, expected_item) 58 except BaseException as e: 59 if check_exception: 60 e.args += (check_exception(actual_item, expected_item),) 61 raise 62 found = True 63 del _actual[i] 64 break 65 if missing_exception: 66 assert found, missing_exception(expected_item) 67 else: 68 assert found 69 if not allow_extra: 70 if extra_exception: 71 assert len(_actual) == 0, [extra_exception(a) for a in _actual] 72 else: 73 assert len(_actual) == 0 74 75def filter_list(f, l): 76 if l is not None: 77 l = list(filter(f, l)) 78 if l == []: 79 l = None 80 return l 81 82def check_cmake(cmake): 83 assert is_dict(cmake) 84 assert sorted(cmake.keys()) == ["generator", "paths", "version"] 85 check_cmake_version(cmake["version"]) 86 check_cmake_paths(cmake["paths"]) 87 check_cmake_generator(cmake["generator"]) 88 89def check_cmake_version(v): 90 assert is_dict(v) 91 assert sorted(v.keys()) == ["isDirty", "major", "minor", "patch", "string", "suffix"] 92 assert is_string(v["string"]) 93 assert is_int(v["major"]) 94 assert is_int(v["minor"]) 95 assert is_int(v["patch"]) 96 assert is_string(v["suffix"]) 97 assert is_bool(v["isDirty"]) 98 99def check_cmake_paths(v): 100 assert is_dict(v) 101 assert sorted(v.keys()) == ["cmake", "cpack", "ctest", "root"] 102 assert is_string(v["cmake"]) 103 assert is_string(v["cpack"]) 104 assert is_string(v["ctest"]) 105 assert is_string(v["root"]) 106 107def check_cmake_generator(g): 108 assert is_dict(g) 109 name = g.get("name", None) 110 assert is_string(name) 111 if name.startswith("Visual Studio"): 112 assert sorted(g.keys()) == ["multiConfig", "name", "platform"] 113 assert is_string(g["platform"]) 114 else: 115 assert sorted(g.keys()) == ["multiConfig", "name"] 116 assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$|Ninja Multi-Config$)")) 117 118def check_index_object(indexEntry, kind, major, minor, check): 119 assert is_dict(indexEntry) 120 assert sorted(indexEntry.keys()) == ["jsonFile", "kind", "version"] 121 assert is_string(indexEntry["kind"]) 122 assert indexEntry["kind"] == kind 123 assert is_dict(indexEntry["version"]) 124 assert sorted(indexEntry["version"].keys()) == ["major", "minor"] 125 assert indexEntry["version"]["major"] == major 126 assert indexEntry["version"]["minor"] == minor 127 assert is_string(indexEntry["jsonFile"]) 128 filepath = os.path.join(reply_dir, indexEntry["jsonFile"]) 129 with open(filepath) as f: 130 object = json.load(f) 131 assert is_dict(object) 132 assert "kind" in object 133 assert is_string(object["kind"]) 134 assert object["kind"] == kind 135 assert "version" in object 136 assert is_dict(object["version"]) 137 assert sorted(object["version"].keys()) == ["major", "minor"] 138 assert object["version"]["major"] == major 139 assert object["version"]["minor"] == minor 140 if check: 141 check(object) 142 143def check_index__test(indexEntry, major, minor): 144 def check(object): 145 assert sorted(object.keys()) == ["kind", "version"] 146 check_index_object(indexEntry, "__test", major, minor, check) 147 148def check_error(value, error): 149 assert is_dict(value) 150 assert sorted(value.keys()) == ["error"] 151 assert is_string(value["error"]) 152 assert value["error"] == error 153 154def check_error_re(value, error): 155 assert is_dict(value) 156 assert sorted(value.keys()) == ["error"] 157 assert is_string(value["error"]) 158 assert re.search(error, value["error"]) 159 160reply_index = sys.argv[1] 161reply_dir = os.path.dirname(reply_index) 162 163with open(reply_index) as f: 164 index = json.load(f) 165