File: testutils.py

package info (click to toggle)
python-libais 0.17%2Bgit.20190917.master.e464cf8-5
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 5,820 kB
  • sloc: cpp: 56,058; python: 11,979; makefile: 537; sh: 466
file content (73 lines) | stat: -rw-r--r-- 1,914 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import re
import six

known_bad = set((
    'addressed',
    'app_id',
    'data',
    'eta',  # TODO(schwehr): Fix this.
    'radio',
    'regional',
    'reserved',
    'structured',
))

precision = 5.0

def TextToNumber(text):
  try:
    return float(text)
  except (TypeError, ValueError):
    return text


def IsNumber(value):
  if isinstance(value, float):
    return True
  if isinstance(value, six.integer_types):
    return True
  return False


def DictDiff(a, b):
  """Compares two dictionaries. Intended to be used in a test to
  compare the actual return value from some function with a
  known-good value.

  Returns a dictionary with the following keys:

    removed: Dict of all key/value pairs in a but not in b.

    added: Dict of all key/value pairs in b but not in a.

    changed: Dict with all keys with different values in a and b.
    Values are pairs of the values from a and b.
  """

  def Compare(x, y):
    if x == y:
      return True
    x = TextToNumber(x)
    y = TextToNumber(y)
    if isinstance(x, six.string_types) and isinstance(y, six.string_types):
      # Collapse strings to just lower case a-z to avoid simple mismatches.
      new_x = re.sub(r'[^a-z]', r'', six.text_type(x).lower())
      new_y = re.sub(r'[^a-z]', r'', six.text_type(y).lower())
      if new_x == new_y:
        return True
    if IsNumber(x) and IsNumber(y):
      if abs(float(x) - float(y)) < precision:
        return True
    return False

  # TODO(redhog): Use sets and make this easier to follow.
  return {
      'removed': {key: a[key] for key in a
                  if key not in b and key not in known_bad},
      'changed': {key: (a[key], b[key]) for key in a
                  if key in b
                  and key not in known_bad
                  and not Compare(a[key], b[key])},
      'added': {key: b[key] for key in b
                if key not in a and key not in known_bad}
  }