import sys import os import json import re if sys.version_info[0] >= 3: unicode = str def is_bool(x, val=None): return isinstance(x, bool) and (val is None or x == val) def is_dict(x): return isinstance(x, dict) def is_list(x): return isinstance(x, list) def is_int(x, val=None): return (isinstance(x, int) or isinstance(x, long)) and (val is None or x == val) def is_string(x, val=None): return (isinstance(x, str) or isinstance(x, unicode)) and (val is None or x == val) def matches(s, pattern): return is_string(s) and bool(re.search(pattern, s)) def check_list_match(match, actual, expected, check=None, check_exception=None, missing_exception=None, extra_exception=None, allow_extra=False): """ Handle the common pattern of making sure every actual item "matches" some item in the expected list, and that neither list has extra items after matching is completed. @param match: Callback to check if an actual item matches an expected item. Return True if the item matches, return False if the item doesn't match. @param actual: List of actual items to search. @param expected: List of expected items to match. @param check: Optional function to check that the actual item is valid by comparing it to the expected item. @param check_exception: Optional function that returns an argument to append to any exception thrown by the check function. @param missing_exception: Optional function that returns an argument to append to the exception thrown when an item is not found. @param extra_exception: Optional function that returns an argument to append to the exception thrown when an extra item is found. @param allow_extra: Optional parameter allowing there to be extra actual items after all the expected items have been found. """ assert is_list(actual) _actual = actual[:] for expected_item in expected: found = False for i, actual_item in enumerate(_actual): if match(actual_item, expected_item): if check: try: check(actual_item, expected_item) except BaseException as e: if check_exception: e.args += (check_exception(actual_item, expected_item),) raise found = True del _actual[i] break if missing_exception: assert found, missing_exception(expected_item) else: assert found if not allow_extra: if extra_exception: assert len(_actual) == 0, [extra_exception(a) for a in _actual] else: assert len(_actual) == 0 def filter_list(f, l): if l is not None: l = list(filter(f, l)) if l == []: l = None return l def check_cmake(cmake): assert is_dict(cmake) assert sorted(cmake.keys()) == ["generator", "paths", "version"] check_cmake_version(cmake["version"]) check_cmake_paths(cmake["paths"]) check_cmake_generator(cmake["generator"]) def check_cmake_version(v): assert is_dict(v) assert sorted(v.keys()) == ["isDirty", "major", "minor", "patch", "string", "suffix"] assert is_string(v["string"]) assert is_int(v["major"]) assert is_int(v["minor"]) assert is_int(v["patch"]) assert is_string(v["suffix"]) assert is_bool(v["isDirty"]) def check_cmake_paths(v): assert is_dict(v) assert sorted(v.keys()) == ["cmake", "cpack", "ctest", "root"] assert is_string(v["cmake"]) assert is_string(v["cpack"]) assert is_string(v["ctest"]) assert is_string(v["root"]) def check_cmake_generator(g): assert is_dict(g) name = g.get("name", None) assert is_string(name) if name.startswith("Visual Studio"): assert sorted(g.keys()) == ["multiConfig", "name", "platform"] assert is_string(g["platform"]) else: assert sorted(g.keys()) == ["multiConfig", "name"] assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$|Ninja Multi-Config$)")) def check_index_object(indexEntry, kind, major, minor, check): assert is_dict(indexEntry) assert sorted(indexEntry.keys()) == ["jsonFile", "kind", "version"] assert is_string(indexEntry["kind"]) assert indexEntry["kind"] == kind assert is_dict(indexEntry["version"]) assert sorted(indexEntry["version"].keys()) == ["major", "minor"] assert indexEntry["version"]["major"] == major assert indexEntry["version"]["minor"] == minor assert is_string(indexEntry["jsonFile"]) filepath = os.path.join(reply_dir, indexEntry["jsonFile"]) with open(filepath) as f: object = json.load(f) assert is_dict(object) assert "kind" in object assert is_string(object["kind"]) assert object["kind"] == kind assert "version" in object assert is_dict(object["version"]) assert sorted(object["version"].keys()) == ["major", "minor"] assert object["version"]["major"] == major assert object["version"]["minor"] == minor if check: check(object) def check_index__test(indexEntry, major, minor): def check(object): assert sorted(object.keys()) == ["kind", "version"] check_index_object(indexEntry, "__test", major, minor, check) def check_error(value, error): assert is_dict(value) assert sorted(value.keys()) == ["error"] assert is_string(value["error"]) assert value["error"] == error def check_error_re(value, error): assert is_dict(value) assert sorted(value.keys()) == ["error"] assert is_string(value["error"]) assert re.search(error, value["error"]) reply_index = sys.argv[1] reply_dir = os.path.dirname(reply_index) with open(reply_index) as f: index = json.load(f)