94 строки
3.2 KiB
Python
94 строки
3.2 KiB
Python
"""Utility functions for tests."""
|
|
import pprint
|
|
from typing import List
|
|
|
|
from google.cloud import bigquery
|
|
from google.cloud.bigquery.schema import SchemaField
|
|
|
|
|
|
def get_differences(expected, result, path="", sep="."):
|
|
"""
|
|
Get the differences between two JSON-like python objects.
|
|
|
|
For complicated objects, this is a big improvement over pytest -vv.
|
|
"""
|
|
differences = []
|
|
|
|
if expected is not None and result is None:
|
|
differences.append(("Expected exists but not Result", path))
|
|
if expected is None and result is not None:
|
|
differences.append(("Result exists but not Expected", path))
|
|
if expected is None and result is None:
|
|
return differences
|
|
|
|
exp_is_dict, res_is_dict = isinstance(expected, dict), isinstance(result, dict)
|
|
exp_is_list, res_is_list = isinstance(expected, list), isinstance(result, list)
|
|
if exp_is_dict and not res_is_dict:
|
|
differences.append(("Expected is dict but not Result", path))
|
|
elif res_is_dict and not exp_is_dict:
|
|
differences.append(("Result is dict but not Expected", path))
|
|
elif not exp_is_dict and not res_is_dict:
|
|
if exp_is_list and res_is_list:
|
|
for i in range(max(len(expected), len(result))):
|
|
if i >= len(result):
|
|
differences.append(
|
|
(f"Result missing element {expected[i]}", path + sep + str(i))
|
|
)
|
|
elif i >= len(expected):
|
|
differences.append(
|
|
(
|
|
f"Result contains extra element {result[i]}",
|
|
path + sep + str(i),
|
|
)
|
|
)
|
|
else:
|
|
differences += get_differences(
|
|
expected[i], result[i], path + sep + str(i)
|
|
)
|
|
elif expected != result:
|
|
differences.append((f"Expected={expected}, Result={result}", path))
|
|
else:
|
|
exp_keys, res_keys = set(expected.keys()), set(result.keys())
|
|
in_exp_not_res, in_res_not_exp = exp_keys - res_keys, res_keys - exp_keys
|
|
|
|
for k in in_exp_not_res:
|
|
differences.append(("In Expected, not in Result", path + sep + k))
|
|
for k in in_res_not_exp:
|
|
differences.append(("In Result, not in Expected", path + sep + k))
|
|
|
|
for k in exp_keys & res_keys:
|
|
differences += get_differences(expected[k], result[k], path + sep + k)
|
|
|
|
return differences
|
|
|
|
|
|
def print_and_test(expected, result=None, actual=None):
|
|
"""Print objects and differences, then test equality."""
|
|
pp = pprint.PrettyPrinter(indent=2)
|
|
if actual is not None:
|
|
result = actual
|
|
|
|
print("\nExpected:")
|
|
pp.pprint(expected)
|
|
|
|
print("\nActual:")
|
|
pp.pprint(result)
|
|
|
|
print("\nDifferences:")
|
|
print("\n".join([" - ".join(v) for v in get_differences(expected, result)]))
|
|
|
|
assert result == expected
|
|
|
|
|
|
def get_mock_bq_client(schema: List[SchemaField]):
|
|
"""Get a mock BQ client that will return a specified schema."""
|
|
|
|
class MockClient:
|
|
"""Mock bigquery.Client."""
|
|
|
|
def get_table(self, table_ref):
|
|
"""Mock bigquery.Client.get_table."""
|
|
return bigquery.Table(table_ref, schema=schema)
|
|
|
|
return MockClient()
|