lookml-generator/tests/utils.py

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