| 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) |