Anonymous avatar Anonymous committed b5a0298

Initial HG import.

Comments (0)

Files changed (3)

+============
+dict_compare
+============
+
+dict_compare compares two python dictionaries and reports on any
+differences between them. 
+
+This can be very handy when comparing dictionary structures. Typical
+case is comparing expected and received values in a unittest. 
+
+The typical use case is::
+
+  import unittest
+  from dict_compare import dict_compare
+
+  class TestSample(unittest.TestCase):
+      def test_someExample(self):
+          expected_dict = {
+              'foo': 'bar',
+              'quux': ['some', 'more']
+          }
+          received_dict = {
+              'foo': 'bar',
+              'quux': ['some', 'other']
+          }
+          self.assertTrue( dict_compare(expected_dict, received_dict, reporter=self.fail) )
+
+  if __name__ == '__main__':
+      unittest.main()
+
+Have fun!
+
+"""
+This module implements a structure comparer
+
+>>> da  = {1:"a"}
+>>> dict_compare(da,da)
+True
+>>> dab = {1:"a",2:"b"}
+>>> dict_compare(da,dab)
+False
+>>> dict_compare(dab,da)
+False
+>>> da2  = {1:"A"}
+>>> dict_compare(da,da2)
+False
+
+# Probando con datos con tuples []
+>>> sr = SimpleReporter()
+>>> db   = {1:['foo', 'bar']}
+>>> dict_compare(db,db,sr)
+True
+>>> sr.get_errors()
+
+>>> sr = SimpleReporter()
+>>> db2  = {1:['bar', 'foo']}
+>>> dict_compare(db,db2,sr)
+False
+>>> len(sr.get_errors())
+60
+
+>>> sr = SimpleReporter()
+>>> dc   = ['a', {'foo': 'bar'}]
+>>> dict_compare(dc,dc,sr)
+True
+>>> dc2  = ['b', {'foo': 'bar'}]
+>>> dict_compare(dc,dc2,sr)
+False
+>>> len(sr.get_errors())
+38
+
+>>> sr  = SimpleReporter()
+>>> dd  = ['a']
+>>> dd2 = {'k': 'v'}
+>>> dict_compare(dd,dd2,sr)
+False
+>>> len(sr.get_errors())
+60
+"""
+import sys
+import os
+
+def listToDict(l):
+    d = {}
+    for (k,v) in enumerate(l):
+        d[k] = v
+    return d
+
+def reportNotFoundKeysIn(d1,d2,label):
+    if isinstance(d1, (list, tuple)):
+        d1 = listToDict(d1)
+        d2 = listToDict(d2)
+    difference = dict( [(key,value) for key,value in d1.iteritems() if not key in d2] )
+    if difference:
+        return label + str( difference ) + os.linesep
+    else:
+        return ""
+
+def dict_compare(d_expected, d_received, reporter=None):
+    if cmp(d_expected,d_received)==0:
+        return True
+    if reporter != None:
+        msg = ""
+        if type(d_expected) == type(d_received):
+            msg += reportNotFoundKeysIn(d_expected,d_received,"Not In Received: ")
+            msg += reportNotFoundKeysIn(d_received,d_expected,"Not In Expected: ")
+            # report keys with different values
+            differentKeysLabelShown = False
+            if isinstance(d_expected, (list, tuple)):
+                d_expected = listToDict(d_expected)
+                d_received = listToDict(d_received)
+            for expected_key in d_expected.keys():
+                if expected_key in d_received:
+                    if d_expected[expected_key] != d_received[expected_key]:
+                        if not differentKeysLabelShown:
+                            msg += "Different values in"+os.linesep
+                        msg += "'%s':  %s != %s " % (   repr(expected_key),
+                                                        repr(d_expected[expected_key]),
+                                                        repr(d_received[expected_key])) + os.linesep
+        else:
+            msg += ( "Not same type: "
+                     + repr(d_expected)+ repr(type(d_expected)) + " != "
+                     + repr(d_received)+ repr(type(d_received)) )
+        reporter(msg)
+                    
+    return False
+
+class SimpleReporter(object):
+    def __init__(self):
+        self._msg = None
+    def __call__(self, msg):
+        self._msg = msg
+    def get_errors(self):
+        return self._msg
+
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()
+
+# -*- coding: utf-8 -*-
+try:
+    from setuptools import setup, find_packages
+except ImportError:
+    from ez_setup import use_setuptools
+    use_setuptools()
+    from setuptools import setup, find_packages
+
+setup(name='dict_compare',
+      version='1.0.1',
+      maintainer='Marijn Vriens',
+      maintainer_email="marijn+dictcompare@metronomo.cl",
+      license='BSD', 
+      keywords='dictionary dict compare library testing',
+      description='''A dictionary comparer with decent difference reporting''',
+      long_description='''dict_compare compares two python dictionaries and reports on any
+differences between them. 
+
+This can be very handy when comparing dictionary structures. Typical
+case is comparing expected and received values in a unittest. 
+''',
+      classifiers=["Development Status :: 5 - Production/Stable",
+                   "Intended Audience :: Developers",
+                   "License :: OSI Approved :: BSD License",
+                   "Programming Language :: Python",
+                   "Topic :: Software Development :: Libraries",
+                   "Topic :: Software Development :: Testing"],
+      py_modules=['dict_compare'],
+      )
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.