1#!/usr/bin/env python3
 2
 3"""Support functions for automated tests."""
 4
 5import sys
 6
 7from chart.common.traits import is_listlike
 8
 9target = sys.stdout
10
11def show(title, obj):
12    """Pretty print a packet body."""
13    target.write(title + '\n')
14    # import pprint
15    # pprint.pprint(obj, compact=True)
16    for k, v in obj.items():
17        target.write('    {k}: {v}\n'.format(k=k, v=v))
18
19def is_scalar(obj):
20    return isinstance(obj, (int, float))
21
22def compare_imp(req, act):
23    """Return None if match, otherwise a list of strings of miscompare messages."""
24    # print('comparing ' + str(req) + ' to ' + str(act))
25    if type(req) is not type(act):
26        return ['Mismatch in type between {a} and {b}'.format(a=type(req), b=type(act))]
27
28    if isinstance(req, dict):
29        compare(sorted(req.keys()), sorted(act.keys()))
30        for k in req.keys():
31            res = compare_imp(req[k], act[k])
32            if res:
33                return ['Problem in {k}'.format(k=k)] + res
34
35    elif is_listlike(req):
36        if len(req) != len(act):
37            return ['Required length {r} does not match {a}'.format(r=len(req), a=len(act))]
38
39        for i, (r, a) in enumerate(zip(req, act)):
40            res = compare_imp(r, a)
41            if res:
42                return ['In item {i}'.format(i=i)] + res
43
44    else:
45        if req != act:
46            return ['Required value {r} type {rt} not found got {a} type {at} instead'.format(
47                r=req, a=act, rt=type(req), at=type(act))]
48
49    return None  # good
50
51def compare(req, act):
52    """Raise an assert exception if required and actual value mismatch."""
53    res = compare_imp(req, act)
54    if res is not None:
55        raise AssertionError('. '.join(res))