class TestBeforeSave(TestCase): def setUp(self): Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) class Basic(MappedClass): class __mongometa__: name = 'hook' session = self.session def before_save(instance): instance.a = 9 _id = FieldProperty(S.ObjectId) a = FieldProperty(int) Mapper.compile_all() self.Basic = Basic self.session.remove(self.Basic) def test_hook_base(self): doc = self.Basic() doc.a = 5 self.session.flush() # first insert self.session.close() doc = self.Basic.query.get(doc._id) assert doc.a == 9, doc.a doc.a = 6 self.session.flush() # then save self.session.close() doc = self.Basic.query.get(doc._id) assert doc.a == 9, doc.a
class TestBasicMapping(TestCase): def setUp(self): self.datastore = create_datastore('mim:///test_db') session = Session(bind=self.datastore) self.session = ODMSession(session) basic = collection('basic', session, Field('_id', S.ObjectId), Field('a', int), Field('b', [int]), Field('c', dict(d=int, e=int))) class Basic(object): pass self.session.mapper(Basic, basic) self.basic = basic self.Basic = Basic def tearDown(self): self.session.clear() self.datastore.conn.drop_all() def test_set_to_same(self): obj = self.Basic(a=1) assert state(obj).status == 'new' self.session.flush() assert state(obj).status == 'clean' obj.a = 1 assert state(obj).status == 'clean' def test_disable_instrument(self): # Put a doc in the DB self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() # Load back with instrumentation self.session.clear() obj = self.Basic.query.find().options(instrument=True).first() self.assertEqual(type(obj.b), InstrumentedList) self.assertEqual(type(obj.c), InstrumentedObj) # Load back without instrumentation self.session.clear() obj = self.Basic.query.find().options(instrument=False).first() self.assertEqual(type(obj.b), list) self.assertEqual(type(obj.c), Object) def test_enable_instrument(self): session = Session(bind=self.datastore) basic1 = collection('basic1', session, Field('_id', S.ObjectId), Field('a', int), Field('b', [int]), Field('c', dict(d=int, e=int))) class Basic1(object): pass self.session.mapper(Basic1, basic1, options=dict(instrument=False)) # Put a doc in the DB Basic1(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() # Load back with instrumentation self.session.clear() obj = Basic1.query.find().options(instrument=True).first() self.assertEqual(type(obj.b), InstrumentedList) self.assertEqual(type(obj.c), InstrumentedObj) # Load back without instrumentation self.session.clear() obj = Basic1.query.find().options(instrument=False).first() self.assertEqual(type(obj.b), list) self.assertEqual(type(obj.c), Object) def test_repr(self): doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) sdoc = repr(doc) # sometimes there's a line break in the repr sdoc_cleaned = sdoc.replace('\n ', '') assert 'a=1' in sdoc_cleaned, sdoc_cleaned assert 'b=I[2, 3]' in sdoc_cleaned, sdoc_cleaned # order is not guaranteed with dictionaries assert "c=I{'d': 4, 'e': 5}" in sdoc_cleaned or \ "c=I{'e': 5, 'd': 4}" in sdoc_cleaned, sdoc_cleaned def test_create(self): doc = self.Basic() assert state(doc).status == 'new' self.session.flush() assert state(doc).status == 'clean' doc.a = 5 assert state(doc).status == 'dirty' self.session.flush() assert state(doc).status == 'clean' c = doc.c c.e = 5 assert state(doc).status == 'dirty', state(doc).status assert repr(state(doc)).startswith('<ObjectState') def test_mapped_object(self): doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.assertEqual(doc.a, doc['a']) self.assertRaises(AttributeError, getattr, doc, 'foo') self.assertRaises(KeyError, doc.__getitem__, 'foo') doc['a'] = 5 self.assertEqual(doc.a, doc['a']) self.assertEqual(doc.a, 5) self.assert_('a' in doc) doc.delete() def test_mapper(self): m = mapper(self.Basic) assert repr(m) == '<Mapper Basic:basic>' self.datastore.db.basic.insert( dict(a=1, b=[2, 3], c=dict(d=4, e=5), f='unknown')) obj = self.Basic.query.find().options(instrument=False).first() q = self.Basic.query.find() self.assertEqual(q.count(), 1) self.session.remove(self.Basic, {}) q = self.Basic.query.find() self.assertEqual(q.count(), 0) def test_query(self): doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() q = self.Basic.query.find(dict(a=1)) self.assertEqual(q.count(), 1) doc.a = 5 self.session.flush() q = self.Basic.query.find(dict(a=1)) self.assertEqual(q.count(), 0) self.assertEqual(doc.query.find(dict(a=1)).count(), 0) self.assertEqual(doc.query.find(dict(b=doc.b)).count(), 1) doc = self.Basic.query.get(a=5) self.assert_(doc is not None) self.Basic.query.remove({}) self.assertEqual(self.Basic.query.find().count(), 0) def test_query_fields(self): doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() self.session.clear() q = self.Basic.query.find(dict(a=1), projection=['b']) self.assertEqual(q.count(), 1) o = q.first() self.assertEqual(o.b, [2, 3]) self.assertEqual(o.a, None) o.b = [4, 5] self.session.flush() self.session.clear() q = self.Basic.query.find(dict(a=1)) self.assertEqual(q.count(), 1) o = q.first() self.assertEqual(o.a, 1) self.assertEqual(o.b, [4, 5]) self.assertEqual(o.c, dict(d=4, e=5)) self.Basic.query.remove({}) self.assertEqual(self.Basic.query.find().count(), 0) def test_delete(self): doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() q = self.Basic.query.find() self.assertEqual(q.count(), 1) doc.delete() q = self.Basic.query.find() self.assertEqual(q.count(), 1) self.session.flush() q = self.Basic.query.find() self.assertEqual(q.count(), 0) doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() q = self.Basic.query.find() self.assertEqual(q.count(), 1) def test_imap(self): doc = self.Basic(a=1, b=[2, 3], c=dict(d=4, e=5)) self.session.flush() doc1 = self.Basic.query.get(_id=doc._id) self.assert_(doc is doc1) self.session.expunge(doc) doc1 = self.Basic.query.get(_id=doc._id) self.assert_(doc is not doc1) self.session.expunge(doc) self.session.expunge(doc) self.session.expunge(doc) @patch('ming.mim.Collection.aggregate') def test_aggregate(self, pymongo_aggregate): self.Basic.query.aggregate([]) assert pymongo_aggregate.called @patch('ming.mim.Collection.map_reduce') def test_map_reduce(self, mim_map_reduce): self.Basic.query.map_reduce('...', '...', {}) assert mim_map_reduce.called @patch('ming.mim.Collection.distinct') def test_distinct(self, mim_distinct): self.Basic.query.distinct('field') assert mim_distinct.called @patch('ming.mim.Cursor.distinct') def test_cursor_distinct(self, mim_distinct): self.Basic.query.find({'a': 'b'}).distinct('field') assert mim_distinct.called @patch('pymongo.collection.Collection.inline_map_reduce') def test_inline_map_reduce(self, pymongo_inline_map_reduce): self.Basic.query.inline_map_reduce() assert pymongo_inline_map_reduce.called @patch('pymongo.collection.Collection.group') def test_group(self, pymongo_group): self.Basic.query.group() assert pymongo_group.called def test_multiple_update_flushes(self): initial_doc = self.Basic() initial_doc.a = 1 self.session.flush() self.session.close() doc_updating = self.Basic.query.get(_id=initial_doc._id) doc_updating.a = 2 self.session.flush() doc_updating.a = 1 # back to "initial" value doc_updating.e = 'foo' # change something else too self.session.flush() self.session.close() doc_after_updates = self.Basic.query.get(_id=doc_updating._id) assert doc_after_updates.a == 1