[Zope3-checkins] CVS: Zope3/src/zope/app/tests - __init__.py:1.1.2.1 annotations.py:1.1.2.1 placelesssetup.py:1.1.2.1 test_attributeannotations.py:1.1.2.1 test_datetimeparse.py:1.1.2.1 test_dependable.py:1.1.2.1 test_introspector.py:1.1.2.1 test_standard_dates.py:1.1.2.1 test_undo.py:1.1.2.1 test_zodbundomanager.py:1.1.2.1

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:32:33 -0500


Update of /cvs-repository/Zope3/src/zope/app/tests
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/app/tests

Added Files:
      Tag: NameGeddon-branch
	__init__.py annotations.py placelesssetup.py 
	test_attributeannotations.py test_datetimeparse.py 
	test_dependable.py test_introspector.py test_standard_dates.py 
	test_undo.py test_zodbundomanager.py 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/app/tests/__init__.py ===
#
# This file is necessary to make this directory a package.


=== Added File Zope3/src/zope/app/tests/annotations.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""

Revision information:
$Id: annotations.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from zope.interface.verify import verifyObject
from zope.app.interfaces.annotation import IAnnotations

class Annotations:
    """
    Test the IAnnotations interface.  Expects the IAnnotations
    to be in self.annotations
    """

    def setUp(self):
        self.obj = {1:2, 3:4}

    def testInterfaceVerifies(self):
        verifyObject(IAnnotations, self.annotations)

    def testStorage(self):
        # test __getitem__
        self.annotations['unittest'] = self.obj
        res = self.annotations['unittest']
        self.failUnlessEqual(self.obj, res)

    def testGetitemException(self):
        # test __getitem__ raises exception on unknown key
        self.assertRaises(KeyError, self.annotations.__getitem__,'randomkey')

    def testGet(self):
        # test get
        self.annotations['unittest'] = obj
        res = self.annotations.get('unittest')
        self.failUnlessEqual(obj, res)

    def testGet(self):
        # test get with no set
        res = self.annotations.get('randomkey')
        self.failUnlessEqual(None, res)

    def testGetDefault(self):
        # test get returns default
        res = self.annotations.get('randomkey', 'default')
        self.failUnlessEqual('default', res)

    def testDel(self):
        self.annotations['unittest'] = self.obj
        del self.annotations['unittest']
        self.failUnlessEqual(None, self.annotations.get('unittest'))

    def testDelRaisesKeyError(self):
        self.assertRaises(KeyError, self.annotations.__delitem__, 'unittest')


=== Added File Zope3/src/zope/app/tests/placelesssetup.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""Unit test logic for setting up and tearing down basic infrastructure


$Id: placelesssetup.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from zope.component.tests.placelesssetup \
     import PlacelessSetup as CAPlacelessSetup
from zope.app.component.tests.placelesssetup \
     import PlacelessSetup as ACAPlacelessSetup
from zope.app.event.tests.placelesssetup \
     import PlacelessSetup as EventPlacelessSetup


class PlacelessSetup(CAPlacelessSetup, ACAPlacelessSetup, EventPlacelessSetup):

    def setUp(self):
        CAPlacelessSetup.setUp(self)
        ACAPlacelessSetup.setUp(self)
        EventPlacelessSetup.setUp(self)


=== Added File Zope3/src/zope/app/tests/test_attributeannotations.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""

Revision information:
$Id: test_attributeannotations.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from unittest import TestCase, TestSuite, main, makeSuite
from zope.testing.cleanup import CleanUp # Base class w registry cleanup
from zope.app.tests.annotations import Annotations
from zope.app.attributeannotations import AttributeAnnotations
from zope.app.interfaces.annotation \
    import IAttributeAnnotatable

class Dummy:
    __implements__ = IAttributeAnnotatable

class Test(CleanUp, Annotations, TestCase):
    
    def setUp(self):
        self.annotations = AttributeAnnotations(Dummy())
        #super(Test,self).setUp()
        Annotations.setUp(self)
        CleanUp.setUp(self)


def test_suite():
    return makeSuite(Test)

if __name__=='__main__':
    main(defaultTest='test_suite')


=== Added File Zope3/src/zope/app/tests/test_datetimeparse.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
import unittest, sys
from zope.app.datetime import parse, time, DateTimeError

class Test(unittest.TestCase):

    def testParse(self):
        from zope.app.datetime import parse

        self.assertEqual(parse('1999 12 31')[:6],
                         (1999, 12, 31, 0, 0, 0))
        self.assertEqual(parse('1999 12 31 EST'),
                         (1999, 12, 31, 0, 0, 0, 'EST'))
        self.assertEqual(parse('Dec 31, 1999')[:6],
                         (1999, 12, 31, 0, 0, 0))
        self.assertEqual(parse('Dec 31 1999')[:6],
                         (1999, 12, 31, 0, 0, 0))
        self.assertEqual(parse('Dec 31 1999')[:6],
                         (1999, 12, 31, 0, 0, 0))
        self.assertEqual(parse('1999/12/31 1:2:3')[:6],
                         (1999, 12, 31, 1, 2, 3))
        self.assertEqual(parse('1999-12-31 1:2:3')[:6],
                         (1999, 12, 31, 1, 2, 3))
        self.assertEqual(parse('1999-12-31T01:02:03')[:6],
                         (1999, 12, 31, 1, 2, 3))
        self.assertEqual(parse('1999-31-12 1:2:3')[:6],
                         (1999, 12, 31, 1, 2, 3))
        self.assertEqual(parse('1999-31-12 1:2:3.456')[:5],
                         (1999, 12, 31, 1, 2))
        self.assertEqual(int(parse('1999-31-12 1:2:3.456')[5]*1000+.000001),
                         3456)
        self.assertEqual(parse('1999-12-31T01:02:03.456')[:5],
                         (1999, 12, 31, 1, 2))
        self.assertEqual(int(parse('1999-12-31T01:02:03.456')[5]*1000+.000001),
                         3456)
        self.assertEqual(parse('Tue, 24 Jul 2001 09:41:03 -0400'),
                         (2001, 7, 24, 9, 41, 3, '-0400'))
        self.assertEqual(parse('1999-12-31T01:02:03.456-12')[6], '-1200')
        self.assertEqual(parse('1999-12-31T01:02:03.456+0030')[6], '+0030')
        self.assertEqual(parse('1999-12-31T01:02:03.456-00:30')[6], '-0030')

    def testTime(self):
        from time import gmtime
        from zope.app.datetime import time
        self.assertEqual(gmtime(time('1999 12 31 GMT'))[:6],
                         (1999, 12, 31, 0, 0, 0))
        self.assertEqual(gmtime(time('1999 12 31 EST'))[:6],
                         (1999, 12, 31, 5, 0, 0))
        self.assertEqual(gmtime(time('1999 12 31 -0500'))[:6],
                         (1999, 12, 31, 5, 0, 0))
        self.assertEqual(gmtime(time('1999-12-31T00:11:22Z'))[:6],
                         (1999, 12, 31, 0, 11, 22))
        self.assertEqual(gmtime(time('1999-12-31T01:11:22+01:00'))[:6],
                         (1999, 12, 31, 0, 11, 22))

    def testBad(self):
        from zope.app.datetime import time, DateTimeError
        self.assertRaises(DateTimeError, parse, '1999-31-12 1:2:63.456')
        self.assertRaises(DateTimeError, parse, '1999-31-13 1:2:3.456')
        self.assertRaises(DateTimeError, parse, '1999-2-30 1:2:3.456')
        self.assertRaises(DateTimeError, parse, 'April 31, 1999 1:2:3.456')

    def testLeap(self):
        from zope.app.datetime import time, DateTimeError
        self.assertRaises(DateTimeError, parse, '1999-2-29 1:2:3.456')
        self.assertRaises(DateTimeError, parse, '1900-2-29 1:2:3.456')
        self.assertEqual(parse('2000-02-29 1:2:3')[:6],
                         (2000, 2, 29, 1, 2, 3))
        self.assertEqual(parse('2004-02-29 1:2:3')[:6],
                         (2004, 2, 29, 1, 2, 3))

    def test_tzoffset(self):
        from zope.app.datetime import _tzoffset
        self.assertEqual(_tzoffset('-0400', None), -4*60*60)
        self.assertEqual(_tzoffset('-0030', None), -30*60)
        self.assertEqual(_tzoffset('+0200', None), 2*60*60)
        self.assertEqual(_tzoffset('EET', None), 2*60*60)

    def testParseDatetimetz(self):
        from datetime import datetimetz
        from zope.app.datetime import parseDatetimetz, tzinfo
        self.assertEqual(parseDatetimetz('1999-12-31T01:02:03.037-00:30'),
                         datetimetz(1999, 12, 31, 1, 2, 3, 37000, tzinfo(-30)))

def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/tests/test_dependable.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""XXX short summary goes here.

XXX longer description goes here.

$Id: test_dependable.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from unittest import TestCase, TestSuite, main, makeSuite
from zope.app.attributeannotations \
     import AttributeAnnotations
from zope.app.tests.placelesssetup import PlacelessSetup
class C:pass

class Test(PlacelessSetup, TestCase):

    
    def _Test__new(self):
        from zope.app.dependable import Dependable
        return Dependable(AttributeAnnotations(C()))

    def testVerifyInterface(self):
        from zope.interface.verify import verifyObject
        from zope.app.interfaces.dependable import IDependable
        object = self._Test__new()
        verifyObject(IDependable, object)

    def test(self):
        dependable = self._Test__new()
        self.failIf(dependable.dependents())
        dependable.addDependent('/a/b')
        dependable.addDependent('/c/d')
        dependable.addDependent('/c/e')
        dependents = list(dependable.dependents())
        dependents.sort()
        self.assertEqual(dependents, ['/a/b', '/c/d', '/c/e'])
        dependable.removeDependent('/c/d')
        dependents = list(dependable.dependents())
        dependents.sort()
        self.assertEqual(dependents, ['/a/b', '/c/e'])
 
def test_suite():
    return TestSuite((
        makeSuite(Test),
        ))

if __name__=='__main__':
    main(defaultTest='test_suite')


=== Added File Zope3/src/zope/app/tests/test_introspector.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
from zope.interface import Interface
from zope.interface.element import Attribute

class ITestClass(Interface):
    def drool():
        """...drool..."""
        
class BaseTestClass:
    """This is stupid base class"""
    pass

class TestClass(BaseTestClass):
    """This is my stupid doc string"""
    __implements__ = ITestClass
    def drool(self):
        pass
    
class I(Interface):
    """bah blah"""
    
class I2(I):
    """eek"""
    
class I3(I, I2):
    """This is dummy doc string"""
    
    testAttribute1 = Attribute("""This is a dummy attribute.""")
    testAttribute2 = Attribute("""This is a dummy attribute.""")
    
    def one(param):
        """method one"""

    def two(param1, param2):
        """method two"""


"""

Revision information:
$Id: test_introspector.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from zope.interface import Interface
from unittest import TestCase, TestSuite, main, makeSuite
from zope.testing.cleanup import CleanUp
from zope.app.introspector import Introspector



class Test(CleanUp, TestCase):
    """Test Introspector."""

    def testIntrospector(self):
        # Testing introspector
        ints = Introspector(ITestClass)
        self.assertEqual(ints.isInterface(), 1)

        ints = Introspector(TestClass())
        self.assertEqual(ints.isInterface(), 0)
        request = {}
        ints.setRequest(request)
        self.assertEqual(ints.getClass(), 'TestClass')

        ints = Introspector(TestClass)
        self.assertEqual(ints.isInterface(), 0)
        request['PATH_INFO'] = '++module++Zope.App.OFS.Introspector.tests.TestClass.TestClass'
        ints.setRequest(request)
        self.assertEqual(ints.getClass(), 'TestClass')
        self.assertEqual(
            ints.getBaseClassNames(),
            ['Zope.App.OFS.Introspector.tests.TestClass.BaseTestClass'])
        self.assertEqual(
            ints.getModule(),
            'Zope.App.OFS.Introspector.tests.TestClass')
        self.assertEqual(ints.getDocString(), "This is my stupid doc string")
        self.assertEqual(ints.getInterfaces(), (ITestClass,))
        self.assertEqual(
            ints.getInterfaceNames(),
            ['Zope.App.OFS.Introspector.tests.TestClass.ITestClass'])
        self.assertEqual(ints.getExtends(), (BaseTestClass,))

        ints = Introspector(I3)
        self.assertEqual(ints.isInterface(), 1)
        request['PATH_INFO'] = '++module++Zope.App.OFS.Introspector.tests.TestClass.I3'
        ints.setRequest(request)
        self.assertEqual(
            ints.getModule(),
            'Zope.App.OFS.Introspector.tests.TestClass')
        self.assertEqual(ints.getExtends(), (I, I2, ))
        self.assertEqual(
            ints.getDocString(),
            "This is dummy doc string")
        Iname = 'I3'
        bases = ['Zope.App.OFS.Introspector.tests.TestClass.I',
                 'Zope.App.OFS.Introspector.tests.TestClass.I2']
        desc = 'This is dummy doc string'
        m1_name = 'one'
        m1_signature = '(param)'
        m1_desc = 'method one'
        m2_name = 'two'
        m2_signature = '(param1, param2)'
        m2_desc = 'method two'
        methods = [(m1_name, m1_signature, m1_desc),
                   (m2_name, m2_signature, m2_desc),]
        attr_name1 = 'testAttribute1'
        attr_desc1 = 'This is a dummy attribute.'
        attr_name2 = 'testAttribute2'
        attr_desc2 = 'This is a dummy attribute.'
        attributes = [(attr_name1, attr_desc1),
                      (attr_name2, attr_desc2), ]
        details = [Iname, bases, desc, methods, attributes]
        self.assertEqual(ints.getInterfaceDetails(), details)


def test_suite():
    suite = TestSuite()
    suite.addTest(makeSuite(Test))
    return suite


if __name__ == '__main__':
    main(defaultTest='test_suite')


=== Added File Zope3/src/zope/app/tests/test_standard_dates.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
import unittest, sys, time

from zope.app.datetime import time

class Test(unittest.TestCase):

    def testiso8601_date(self):
        from zope.app.datetime import iso8601_date
        self.assertEqual(iso8601_date(time("2000-01-01T01:01:01.234Z")),
                         "2000-01-01T01:01:01Z")

    def testrfc850_date(self):
        from zope.app.datetime import rfc850_date
        self.assertEqual(rfc850_date(time("2002-01-12T01:01:01.234Z")),
                         "Saturday, 12-Jan-02 01:01:01 GMT")

    def testrfc1123_date(self):
        from zope.app.datetime import rfc1123_date
        self.assertEqual(rfc1123_date(time("2002-01-12T01:01:01.234Z")),
                         "Sat, 12 Jan 2002 01:01:01 GMT")

def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/tests/test_undo.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""

Revision information:
$Id: test_undo.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from unittest import TestCase, TestSuite, main, makeSuite

from zope.app.interfaces.undo import IUndoManager
from zope.app.undo import Undo
from zope.app.services.tests.placefulsetup\
           import PlacefulSetup

class TestIUndoManager:
    __implements__ = IUndoManager

    def __init__(self):
        dict1 = {'id': '1', 'user_name': 'monkey', 'description': 'thing1',
 'time': 'today'}
        dict2 = {'id': '2', 'user_name': 'monkey', 'description': 'thing2',
 'time': 'today'}
        dict3 = {'id': '3', 'user_name': 'monkey', 'description': 'thing3',
 'time': 'today'}

        self.dummy_db = [dict1, dict2, dict3]

    def getUndoInfo(self):
        return self.dummy_db

    def undoTransaction(self, id_list):
        # just remove an element for now
        temp_dict = {}
        for db_record in self.dummy_db:
            if db_record['id'] not in id_list:
                temp_dict[db_record['id']] =  db_record

        self.dummy_db = []
        for key in temp_dict.keys():
            self.dummy_db.append(temp_dict[key])


class Test(PlacefulSetup, TestCase):

    def setUp(self):
        PlacefulSetup.setUp(self)
        from zope.component import getService
        getService(None,'Utilities').provideUtility(IUndoManager,
              TestIUndoManager())
        
    def testGetUndoInfo(self):
        view = Undo(None, None)

        self.assertEqual(view.getUndoInfo(), TestIUndoManager().getUndoInfo())
        

    def testUndoSingleTransaction(self):
        view = Undo(None, None)
        id_list = ['1']
        view.action(id_list)

        testum = TestIUndoManager()
        testum.undoTransaction(id_list)

        self.assertEqual(view.getUndoInfo(), testum.getUndoInfo())

    def testUndoManyTransactions(self):
        view = Undo(None, None)
        id_list = ['1','2','3']
        view.action(id_list)

        testum = TestIUndoManager()
        testum.undoTransaction(id_list)

        self.assertEqual(view.getUndoInfo(), testum.getUndoInfo())

def test_suite():
    return makeSuite(Test)

if __name__=='__main__':
    main(defaultTest='test_suite')


=== Added File Zope3/src/zope/app/tests/test_zodbundomanager.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""

Revision information:
$Id: test_zodbundomanager.py,v 1.1.2.1 2002/12/23 19:32:32 jim Exp $
"""

from unittest import TestCase, TestSuite, main, makeSuite
from zope.testing.cleanup import CleanUp # Base class w registry cleanup
from time import time

def dict(**kw): return kw

testdata = [
    dict(id='1', user_name='jim', time=time(), description='des 1'),
    dict(id='2', user_name='jim', time=time(), description='des 2'),
    dict(id='3', user_name='jim', time=time(), description='des 3'),
    dict(id='4', user_name='jim', time=time(), description='des 4'),
    dict(id='5', user_name='jim', time=time(), description='des 5'),
    dict(id='6', user_name='jim', time=time(), description='des 6'),
    dict(id='7', user_name='jim', time=time(), description='des 7'),
    ]
testdata.reverse()

class StubDB:

    def __init__(self):
        self.data = list(testdata)

    def undoInfo(self):
        return tuple(self.data)

    def undo(self, id):
        self.data = [d for d in self.data if d['id'] != id]

class Test(CleanUp, TestCase):

    def test(self):
        from zope.app.undo import ZODBUndoManager
        um = ZODBUndoManager(StubDB())

        self.assertEqual(list(um.getUndoInfo()), testdata)

        um.undoTransaction(('3','4','5'))
        expected = testdata
        expected = [d for d in expected if (d['id'] not in ('3','4','5'))]
        
        self.assertEqual(list(um.getUndoInfo()), expected)

def test_suite():
    return makeSuite(Test)

if __name__=='__main__':
    main(defaultTest='test_suite')