# accessing fields must no raise exceptions...
part.name
# ... except if they are restricted
- with self.assertRaises(openerp.osv.orm.except_orm) as cm:
+ with self.assertRaises(openerp.exceptions.AccessError):
with mute_logger('openerp.models'):
part.email
- self.assertEqual(cm.exception.args[0], 'AccessError')
-
if __name__ == '__main__':
unittest2.main()
with self.assertRaises(Exception):
self.env['test_new_api.message'].create({'discussion': discussion.id, 'body': 'Whatever'})
+ # make sure that assertRaises() does not leave fields to recompute
+ self.assertFalse(self.env.has_todo())
+
# put back oneself into discussion participants: now we can create
# messages in discussion
discussion.participants += self.env.user
env.computed.clear()
env.dirty.clear()
+ def clear(self):
+ """ Clear all record caches, and discard all fields to recompute.
+ This may be useful when recovering from a failed ORM operation.
+ """
+ self.invalidate_all()
+ self.all.todo.clear()
+
+ @contextmanager
+ def clear_upon_failure(self):
+ """ Context manager that clears the environments (caches and fields to
+ recompute) upon exception.
+ """
+ try:
+ yield
+ except Exception:
+ self.clear()
+ raise
+
def field_todo(self, field):
""" Check whether `field` must be recomputed, and returns a recordset
with all records to recompute for `field`.
import unittest2
import urllib2
import xmlrpclib
+from contextlib import contextmanager
from datetime import datetime, timedelta
import werkzeug
module, xid = xid.split('.')
return self.registry('ir.model.data').get_object(self.cr, self.uid, module, xid)
+ @contextmanager
+ def _assertRaises(self, exception):
+ """ Context manager that clears the environment upon failure. """
+ with super(BaseCase, self).assertRaises(exception):
+ with self.env.clear_upon_failure():
+ yield
+
+ def assertRaises(self, exception, func=None, *args, **kwargs):
+ if func:
+ with self._assertRaises(exception):
+ func(*args, **kwargs)
+ else:
+ return self._assertRaises(exception)
+
class TransactionCase(BaseCase):
""" TestCase in which each test method is run in its own transaction,
self.env = api.Environment(self.cr, self.uid, {})
def tearDown(self):
+ # rollback and close the cursor, and reset the environments
+ self.env.reset()
self.cr.rollback()
self.cr.close()
@classmethod
def tearDownClass(cls):
+ # rollback and close the cursor, and reset the environments
+ cls.env.reset()
cls.cr.rollback()
cls.cr.close()
+
class RedirectHandler(urllib2.HTTPRedirectHandler):
"""
HTTPRedirectHandler is predicated upon HTTPErrorProcessor being used and