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