[Checkins] SVN: m01.mongofake/trunk/ - improved dictify method, convert initial given SON data

Roger Ineichen cvs-admin at zope.org
Sun Dec 9 23:13:02 UTC 2012


Log message for revision 128546:
  - improved dictify method, convert initial given SON data
  - added initial tests for helper methods (fake mongodb tests still missing)
  - cleanup setup.py
  - added MANIFEST.in
  - prepare next release
  

Changed:
  U   m01.mongofake/trunk/CHANGES.txt
  A   m01.mongofake/trunk/MANIFEST.in
  U   m01.mongofake/trunk/README.txt
  U   m01.mongofake/trunk/TODO.txt
  U   m01.mongofake/trunk/buildout.cfg
  U   m01.mongofake/trunk/setup.py
  A   m01.mongofake/trunk/src/m01/mongofake/README.txt
  U   m01.mongofake/trunk/src/m01/mongofake/__init__.py
  A   m01.mongofake/trunk/src/m01/mongofake/tests.py

-=-
Modified: m01.mongofake/trunk/CHANGES.txt
===================================================================
--- m01.mongofake/trunk/CHANGES.txt	2012-12-09 10:50:01 UTC (rev 128545)
+++ m01.mongofake/trunk/CHANGES.txt	2012-12-09 23:13:01 UTC (rev 128546)
@@ -2,12 +2,14 @@
 CHANGES
 =======
 
-0.1.1 (unreleased)
+0.1.1 (2012-12-10)
 ------------------
 
-- Nothing changed yet.
+- inproved dictify method, also convert single SON object to dict
 
+- add some initial tests
 
+
 0.1.0 (2012-05-22)
 ------------------
 

Added: m01.mongofake/trunk/MANIFEST.in
===================================================================
--- m01.mongofake/trunk/MANIFEST.in	                        (rev 0)
+++ m01.mongofake/trunk/MANIFEST.in	2012-12-09 23:13:01 UTC (rev 128546)
@@ -0,0 +1,3 @@
+global-include *.txt
+include *.txt
+recursive-include src *.txt

Modified: m01.mongofake/trunk/README.txt
===================================================================
--- m01.mongofake/trunk/README.txt	2012-12-09 10:50:01 UTC (rev 128545)
+++ m01.mongofake/trunk/README.txt	2012-12-09 23:13:01 UTC (rev 128546)
@@ -1,2 +1,2 @@
-This package provides a FAKE mongoDB implementation.
-This is quite handy for testing.
+This package provides a FAKE mongoDB implementation and is quite handy for
+testing.

Modified: m01.mongofake/trunk/TODO.txt
===================================================================
--- m01.mongofake/trunk/TODO.txt	2012-12-09 10:50:01 UTC (rev 128545)
+++ m01.mongofake/trunk/TODO.txt	2012-12-09 23:13:01 UTC (rev 128546)
@@ -2,4 +2,4 @@
 TODO
 ====
 
-add some tests
\ No newline at end of file
+- add some fake mongodb tests
\ No newline at end of file

Modified: m01.mongofake/trunk/buildout.cfg
===================================================================
--- m01.mongofake/trunk/buildout.cfg	2012-12-09 10:50:01 UTC (rev 128545)
+++ m01.mongofake/trunk/buildout.cfg	2012-12-09 23:13:01 UTC (rev 128546)
@@ -6,7 +6,7 @@
 
 [test]
 recipe = zc.recipe.testrunner
-eggs = m01.mongofake [test]
+eggs = m01.mongofake
 
 
 [checker]
@@ -16,7 +16,7 @@
 
 [coverage]
 recipe = zc.recipe.testrunner
-eggs = m01.mongofake [test]
+eggs = m01.mongofake
 defaults = ['--all', '--coverage', '../../coverage']
 
 

Modified: m01.mongofake/trunk/setup.py
===================================================================
--- m01.mongofake/trunk/setup.py	2012-12-09 10:50:01 UTC (rev 128545)
+++ m01.mongofake/trunk/setup.py	2012-12-09 23:13:01 UTC (rev 128546)
@@ -21,7 +21,7 @@
 
 setup(
     name='m01.mongofake',
-    version='0.1.1.dev0',
+    version='0.1.1',
     author='Zope Foundation and Contributors',
     author_email='zope-dev at zope.org',
     description="Fake MongoDB implementation",
@@ -45,10 +45,7 @@
     packages=find_packages('src'),
     include_package_data=True,
     package_dir={'': 'src'},
-    extras_require=dict(
-        test=[
-            'zope.testing',
-        ]),
+    extras_require=dict(),
     install_requires=[
         'setuptools',
         'pymongo',

Added: m01.mongofake/trunk/src/m01/mongofake/README.txt
===================================================================
--- m01.mongofake/trunk/src/m01/mongofake/README.txt	                        (rev 0)
+++ m01.mongofake/trunk/src/m01/mongofake/README.txt	2012-12-09 23:13:01 UTC (rev 128546)
@@ -0,0 +1,157 @@
+======
+README
+======
+
+Let's test some mongofake helper methods.
+
+  >>> import re
+  >>> import datetime
+  >>> import bson.tz_util
+  >>> import m01.mongofake
+  >>> from m01.mongofake import pprint
+
+
+RENormalizer
+------------
+
+The RENormalizer is able to normalize text and produce comparable output. You
+can setup the RENormalizer with a list of input, output expressions. This is
+usefull if you dump mongodb data which contains dates or other not so simple 
+reproducable data. Such a dump result can get normalized before the unit test
+will compare the output. Also see zope.testing.renormalizing for the same
+pattern which is useable as a doctest checker.
+
+  >>> normalizer = m01.mongofake.RENormalizer([
+  ...    (re.compile('[0-9]*[.][0-9]* seconds'), '... seconds'),
+  ...    (re.compile('at 0x[0-9a-f]+'), 'at ...'),
+  ...    ])
+
+  >>> text = """
+  ... <object object at 0xb7f14438>
+  ... completed in 1.234 seconds.
+  ... ...
+  ... <object object at 0xb7f14450>
+  ... completed in 1.234 seconds.
+  ... """
+
+  >>> print normalizer(text)
+  <BLANKLINE>
+  <object object at ...>
+  completed in ... seconds.
+  ...
+  <object object at ...>
+  completed in ... seconds.
+  <BLANKLINE>
+
+Now let's test some mongodb relevant stuff:
+
+  >>> from bson.dbref import DBRef
+  >>> from bson.min_key import MinKey
+  >>> from bson.max_key import MaxKey
+  >>> from bson.objectid import ObjectId
+  >>> from bson.timestamp import Timestamp
+
+  >>> import time
+  >>> import calendar
+  >>> import struct
+  >>> def getObjectId(secs=0):
+  ...    """Knows how to generate similar ObjectId based on integer (counter)"""
+  ...    time_tuple = time.gmtime(secs)
+  ...    ts = calendar.timegm(time_tuple)
+  ...    oid = struct.pack(">i", int(ts)) + "\x00" * 8
+  ...    return ObjectId(oid)
+
+  >>> oid = getObjectId(42)
+  >>> oid
+  ObjectId('0000002a0000000000000000')
+
+  >>> data = {'oid': oid,
+  ...         'dbref': DBRef("foo", 5, "db"),
+  ...         'date': datetime.datetime(2011, 5, 7, 1, 12),
+  ...         'utc': datetime.datetime(2011, 5, 7, 1, 12, tzinfo=bson.tz_util.utc),
+  ...         'min': MinKey(),
+  ...         'max': MaxKey(),
+  ...         'timestamp': Timestamp(4, 13),
+  ...         're': re.compile("a*b", re.IGNORECASE),
+  ...         'string': 'string',
+  ...         'unicode': u'unicode',
+  ...         'int': 42}
+
+Now let's pretty print the data:
+
+  >>> pprint(data)
+  {'date': datetime.datetime(2011, 5, 7, 1, 12),
+   'dbref': DBRef('foo', 5, 'db'),
+   'int': 42,
+   'max': MaxKey(),
+   'min': MinKey(),
+   'oid': ObjectId('0000002a0000000000000000'),
+   're': <_sre.SRE_Pattern object at ...>,
+   'string': 'string',
+   'timestamp': Timestamp(4, 13),
+   'unicode': u'unicode',
+   'utc': datetime.datetime(2011, 5, 7, 1, 12, tzinfo=<bson.tz_util.FixedOffset object at ...>)}
+
+
+reNormalizer
+------------
+
+As you can see our predefined reNormalizer will convert the values using our
+given patterns: 
+
+  >>> import m01.mongofake
+  >>> print m01.mongofake.reNormalizer(data)
+  {'date': datetime.datetime(...),
+   'dbref': DBRef('foo', 5, 'db'),
+   'int': 42,
+   'max': MaxKey(),
+   'min': MinKey(),
+   'oid': ObjectId('...'),
+   're': <_sre.SRE_Pattern object at ...>,
+   'string': 'string',
+   'timestamp': Timestamp('...'),
+   'unicode': u'unicode',
+   'utc': datetime(..., tzinfo=<bson.tz_util.FixedOffset ...>)}
+
+
+pprint
+------
+
+  >>> m01.mongofake.reNormalizer.pprint(data)
+  {'date': datetime.datetime(...),
+   'dbref': DBRef('foo', 5, 'db'),
+   'int': 42,
+   'max': MaxKey(),
+   'min': MinKey(),
+   'oid': ObjectId('...'),
+   're': <_sre.SRE_Pattern object at ...>,
+   'string': 'string',
+   'timestamp': Timestamp('...'),
+   'unicode': u'unicode',
+   'utc': datetime(..., tzinfo=<bson.tz_util.FixedOffset ...>)}
+
+
+dictify
+-------
+
+  >>> import bson.son
+  >>> son = bson.son.SON(data)
+  >>> type(son)
+  <class 'bson.son.SON'>
+
+  >>> res = m01.mongofake.dictify(son)
+  >>> type(res)
+  <type 'dict'>
+
+  >>> m01.mongofake.pprint(res)
+  {'date': datetime.datetime(2011, 5, 7, 1, 12),
+   'dbref': DBRef('foo', 5, 'db'),
+   'int': 42,
+   'max': MaxKey(),
+   'min': MinKey(),
+   'oid': ObjectId('0000002a0000000000000000'),
+   're': <_sre.SRE_Pattern object at ...>,
+   'string': 'string',
+   'timestamp': Timestamp(4, 13),
+   'unicode': u'unicode',
+   'utc': datetime.datetime(2011, 5, 7, 1, 12, tzinfo=<bson.tz_util.FixedOffset object at ...>)}


Property changes on: m01.mongofake/trunk/src/m01/mongofake/README.txt
___________________________________________________________________
Added: svn:keywords
   + Date Author Id Revision
Added: svn:eol-style
   + native

Modified: m01.mongofake/trunk/src/m01/mongofake/__init__.py
===================================================================
--- m01.mongofake/trunk/src/m01/mongofake/__init__.py	2012-12-09 10:50:01 UTC (rev 128545)
+++ m01.mongofake/trunk/src/m01/mongofake/__init__.py	2012-12-09 23:13:01 UTC (rev 128546)
@@ -11,6 +11,9 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+"""
+$Id$
+"""
 __docformat__ = "reStructuredText"
 
 import copy
@@ -18,9 +21,9 @@
 import types
 import pprint as pp
 
-from bson import objectid
-from bson import son
-from pymongo import cursor
+import bson.objectid
+import bson.son
+import pymongo.cursor 
 
 
 ###############################################################################
@@ -31,16 +34,26 @@
 
 # SON to dict converter
 def dictify(data):
-    """Recursive replace SON instance with plain a dict"""
+    """Recursive replace SON items with dict in the given data structure.
+    
+    Compared to the SON.to_dict method, this method will also handle tuples
+    and keep them intact.
+
+    """
+    if isinstance(data, bson.son.SON):
+        data = dict(data)
     if isinstance(data, dict):
         d = {}
-        for k, v in data.items():
+        for k, v in data.iteritems():
+            # replace nested SON items
             d[k] = dictify(v)
     elif isinstance(data, (tuple, list)):
         d = []
         for v in data:
+            # replace nested SON items
             d.append(dictify(v))
         if isinstance(data, tuple):
+            # keep tuples intact 
             d = tuple(d)
     else:
         d = data
@@ -81,7 +94,7 @@
 
     def pprint(self, data):
         """Pretty print data"""
-        if isinstance(data, cursor.Cursor):
+        if isinstance(data, pymongo.cursor.Cursor):
             for item in data:
                 print self(item)
         else:
@@ -370,7 +383,7 @@
         for doc in docs:
             oid = doc.get('_id')
             if oid is None:
-                oid = objectid.ObjectId()
+                oid = bson.objectid.ObjectId()
                 doc[u'_id'] = oid
             d = {}
             for k, v in list(doc.items()):
@@ -389,9 +402,9 @@
                  _sock=None, _must_use_master=False):
         spec = spec_or_object_id
         if spec is None:
-            spec = son.SON()
-        if isinstance(spec, objectid.ObjectId):
-            spec = son.SON({"_id": spec})
+            spec = bson.son.SON()
+        if isinstance(spec, bson.objectid.ObjectId):
+            spec = bson.son.SON({"_id": spec})
 
         for result in self.find(spec, limit=-1, fields=fields,
             slave_okay=slave_okay, _sock=_sock,
@@ -404,7 +417,7 @@
              sort=None,
              _sock=None, _must_use_master=False):
         if spec is None:
-            spec = son.SON()
+            spec = bson.son.SON()
 
         if not isinstance(spec, types.DictType):
             raise TypeError("spec must be an instance of dict")
@@ -435,7 +448,7 @@
 
     def remove(self, spec_or_object_id, safe=False):
         spec = spec_or_object_id
-        if isinstance(spec, objectid.ObjectId):
+        if isinstance(spec, bson.objectid.ObjectId):
             spec = {"_id": spec}
 
         if not isinstance(spec, types.DictType):

Added: m01.mongofake/trunk/src/m01/mongofake/tests.py
===================================================================
--- m01.mongofake/trunk/src/m01/mongofake/tests.py	                        (rev 0)
+++ m01.mongofake/trunk/src/m01/mongofake/tests.py	2012-12-09 23:13:01 UTC (rev 128546)
@@ -0,0 +1,32 @@
+##############################################################################
+#
+# Copyright (c) 2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+import doctest
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocFileSuite('README.txt',
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        ))
+
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: m01.mongofake/trunk/src/m01/mongofake/tests.py
___________________________________________________________________
Added: svn:keywords
   + Date Author Id Revision
Added: svn:eol-style
   + native



More information about the checkins mailing list