Remove DictMatches custom matcher from unit tests
On Py27 assertDictEqual handles nested dictionaries just fine. Change-Id: I0695a1249a3c4153ba4cc49405640a3e09a2af04 Closes-Bug: #1496552
This commit is contained in:
parent
ad9385aae6
commit
9670d2bd26
@ -32,7 +32,6 @@ from ironic.common.glance_service import base_image_service
|
|||||||
from ironic.common.glance_service import service_utils
|
from ironic.common.glance_service import service_utils
|
||||||
from ironic.common import image_service as service
|
from ironic.common import image_service as service
|
||||||
from ironic.tests import base
|
from ironic.tests import base
|
||||||
from ironic.tests import matchers
|
|
||||||
from ironic.tests import stubs
|
from ironic.tests import stubs
|
||||||
|
|
||||||
|
|
||||||
@ -166,10 +165,11 @@ class TestGlanceImageService(base.TestCase):
|
|||||||
'properties': {'instance_id': '42', 'user_id': 'fake'},
|
'properties': {'instance_id': '42', 'user_id': 'fake'},
|
||||||
'owner': None,
|
'owner': None,
|
||||||
}
|
}
|
||||||
self.assertThat(image_meta, matchers.DictMatches(expected))
|
|
||||||
|
self.assertDictEqual(expected, image_meta)
|
||||||
|
|
||||||
image_metas = self.service.detail()
|
image_metas = self.service.detail()
|
||||||
self.assertThat(image_metas[0], matchers.DictMatches(expected))
|
self.assertDictEqual(expected, image_metas[0])
|
||||||
|
|
||||||
def test_create_without_instance_id(self):
|
def test_create_without_instance_id(self):
|
||||||
"""Test creating an image without an instance ID.
|
"""Test creating an image without an instance ID.
|
||||||
@ -200,7 +200,7 @@ class TestGlanceImageService(base.TestCase):
|
|||||||
'owner': None,
|
'owner': None,
|
||||||
}
|
}
|
||||||
actual = self.service.show(image_id)
|
actual = self.service.show(image_id)
|
||||||
self.assertThat(actual, matchers.DictMatches(expected))
|
self.assertDictEqual(expected, actual)
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
fixture = self._make_fixture(name='test image')
|
fixture = self._make_fixture(name='test image')
|
||||||
@ -270,7 +270,7 @@ class TestGlanceImageService(base.TestCase):
|
|||||||
'owner': None,
|
'owner': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.assertThat(meta, matchers.DictMatches(expected))
|
self.assertDictEqual(expected, meta)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
def test_detail_limit(self):
|
def test_detail_limit(self):
|
||||||
@ -326,7 +326,7 @@ class TestGlanceImageService(base.TestCase):
|
|||||||
'deleted': None,
|
'deleted': None,
|
||||||
'owner': None,
|
'owner': None,
|
||||||
}
|
}
|
||||||
self.assertThat(meta, matchers.DictMatches(expected))
|
self.assertDictEqual(expected, meta)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
def test_detail_invalid_marker(self):
|
def test_detail_invalid_marker(self):
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# Copyright 2012 Hewlett-Packard Development Company, L.P.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
"""Matcher classes to be used inside of the testtools assertThat framework."""
|
|
||||||
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
|
|
||||||
class DictKeysMismatch(object):
|
|
||||||
def __init__(self, d1only, d2only):
|
|
||||||
self.d1only = d1only
|
|
||||||
self.d2only = d2only
|
|
||||||
|
|
||||||
def describe(self):
|
|
||||||
return ('Keys in d1 and not d2: %(d1only)s.'
|
|
||||||
' Keys in d2 and not d1: %(d2only)s' %
|
|
||||||
{'d1only': self.d1only, 'd2only': self.d2only})
|
|
||||||
|
|
||||||
def get_details(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class DictMismatch(object):
|
|
||||||
def __init__(self, key, d1_value, d2_value):
|
|
||||||
self.key = key
|
|
||||||
self.d1_value = d1_value
|
|
||||||
self.d2_value = d2_value
|
|
||||||
|
|
||||||
def describe(self):
|
|
||||||
return ("Dictionaries do not match at %(key)s."
|
|
||||||
" d1: %(d1_value)s d2: %(d2_value)s" %
|
|
||||||
{'d1_value': self.d1_value, 'd2_value': self.d2_value})
|
|
||||||
|
|
||||||
def get_details(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class DictMatches(object):
|
|
||||||
|
|
||||||
def __init__(self, d1, approx_equal=False, tolerance=0.001):
|
|
||||||
self.d1 = d1
|
|
||||||
self.approx_equal = approx_equal
|
|
||||||
self.tolerance = tolerance
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return 'DictMatches(%s)' % (pprint.pformat(self.d1))
|
|
||||||
|
|
||||||
# Useful assertions
|
|
||||||
def match(self, d2):
|
|
||||||
"""Assert two dicts are equivalent.
|
|
||||||
|
|
||||||
This is a 'deep' match in the sense that it handles nested
|
|
||||||
dictionaries appropriately.
|
|
||||||
|
|
||||||
NOTE:
|
|
||||||
|
|
||||||
If you don't care (or don't know) a given value, you can specify
|
|
||||||
the string DONTCARE as the value. This will cause that dict-item
|
|
||||||
to be skipped.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
d1keys = set(self.d1.keys())
|
|
||||||
d2keys = set(d2.keys())
|
|
||||||
if d1keys != d2keys:
|
|
||||||
d1only = d1keys - d2keys
|
|
||||||
d2only = d2keys - d1keys
|
|
||||||
return DictKeysMismatch(d1only, d2only)
|
|
||||||
|
|
||||||
for key in d1keys:
|
|
||||||
d1value = self.d1[key]
|
|
||||||
d2value = d2[key]
|
|
||||||
try:
|
|
||||||
error = abs(float(d1value) - float(d2value))
|
|
||||||
within_tolerance = error <= self.tolerance
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
# If both values aren't convertible to float, just ignore
|
|
||||||
# ValueError if arg is a str, TypeError if it's something else
|
|
||||||
# (like None)
|
|
||||||
within_tolerance = False
|
|
||||||
|
|
||||||
if hasattr(d1value, 'keys') and hasattr(d2value, 'keys'):
|
|
||||||
matcher = DictMatches(d1value)
|
|
||||||
did_match = matcher.match(d2value)
|
|
||||||
if did_match is not None:
|
|
||||||
return did_match
|
|
||||||
elif 'DONTCARE' in (d1value, d2value):
|
|
||||||
continue
|
|
||||||
elif self.approx_equal and within_tolerance:
|
|
||||||
continue
|
|
||||||
elif d1value != d2value:
|
|
||||||
return DictMismatch(key, d1value, d2value)
|
|
Loading…
x
Reference in New Issue
Block a user