Add signal_kwargs arg for save/delete/bulk insert
This commit is contained in:
		| @@ -25,6 +25,8 @@ class SignalTests(unittest.TestCase): | ||||
|         connect(db='mongoenginetest') | ||||
|  | ||||
|         class Author(Document): | ||||
|             # Make the id deterministic for easier testing | ||||
|             id = SequenceField(primary_key=True) | ||||
|             name = StringField() | ||||
|  | ||||
|             def __unicode__(self): | ||||
| @@ -33,7 +35,7 @@ class SignalTests(unittest.TestCase): | ||||
|             @classmethod | ||||
|             def pre_init(cls, sender, document, *args, **kwargs): | ||||
|                 signal_output.append('pre_init signal, %s' % cls.__name__) | ||||
|                 signal_output.append(str(kwargs['values'])) | ||||
|                 signal_output.append(kwargs['values']) | ||||
|  | ||||
|             @classmethod | ||||
|             def post_init(cls, sender, document, **kwargs): | ||||
| @@ -43,48 +45,55 @@ class SignalTests(unittest.TestCase): | ||||
|             @classmethod | ||||
|             def pre_save(cls, sender, document, **kwargs): | ||||
|                 signal_output.append('pre_save signal, %s' % document) | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def pre_save_post_validation(cls, sender, document, **kwargs): | ||||
|                 signal_output.append('pre_save_post_validation signal, %s' % document) | ||||
|                 if 'created' in kwargs: | ||||
|                     if kwargs['created']: | ||||
|                         signal_output.append('Is created') | ||||
|                     else: | ||||
|                         signal_output.append('Is updated') | ||||
|                 if kwargs.pop('created', False): | ||||
|                     signal_output.append('Is created') | ||||
|                 else: | ||||
|                     signal_output.append('Is updated') | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def post_save(cls, sender, document, **kwargs): | ||||
|                 dirty_keys = document._delta()[0].keys() + document._delta()[1].keys() | ||||
|                 signal_output.append('post_save signal, %s' % document) | ||||
|                 signal_output.append('post_save dirty keys, %s' % dirty_keys) | ||||
|                 if 'created' in kwargs: | ||||
|                     if kwargs['created']: | ||||
|                         signal_output.append('Is created') | ||||
|                     else: | ||||
|                         signal_output.append('Is updated') | ||||
|                 if kwargs.pop('created', False): | ||||
|                     signal_output.append('Is created') | ||||
|                 else: | ||||
|                     signal_output.append('Is updated') | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def pre_delete(cls, sender, document, **kwargs): | ||||
|                 signal_output.append('pre_delete signal, %s' % document) | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def post_delete(cls, sender, document, **kwargs): | ||||
|                 signal_output.append('post_delete signal, %s' % document) | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def pre_bulk_insert(cls, sender, documents, **kwargs): | ||||
|                 signal_output.append('pre_bulk_insert signal, %s' % documents) | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def post_bulk_insert(cls, sender, documents, **kwargs): | ||||
|                 signal_output.append('post_bulk_insert signal, %s' % documents) | ||||
|                 if kwargs.get('loaded', False): | ||||
|                 if kwargs.pop('loaded', False): | ||||
|                     signal_output.append('Is loaded') | ||||
|                 else: | ||||
|                     signal_output.append('Not loaded') | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|         self.Author = Author | ||||
|         Author.drop_collection() | ||||
|         Author.id.set_next_value(0) | ||||
|  | ||||
|         class Another(Document): | ||||
|  | ||||
| @@ -96,10 +105,12 @@ class SignalTests(unittest.TestCase): | ||||
|             @classmethod | ||||
|             def pre_delete(cls, sender, document, **kwargs): | ||||
|                 signal_output.append('pre_delete signal, %s' % document) | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def post_delete(cls, sender, document, **kwargs): | ||||
|                 signal_output.append('post_delete signal, %s' % document) | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|         self.Another = Another | ||||
|         Another.drop_collection() | ||||
| @@ -137,12 +148,18 @@ class SignalTests(unittest.TestCase): | ||||
|                 for document in documents: | ||||
|                     if not document.active: | ||||
|                         document.active = True | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|             @classmethod | ||||
|             def post_bulk_insert(cls, sender, documents, **kwargs): | ||||
|                 signal_output.append('post_bulk_insert signal, %s' % | ||||
|                                      [(doc, {'active': documents[n].active}) | ||||
|                                       for n, doc in enumerate(documents)]) | ||||
|                 if kwargs.pop('loaded', False): | ||||
|                     signal_output.append('Is loaded') | ||||
|                 else: | ||||
|                     signal_output.append('Not loaded') | ||||
|                 signal_output.append(kwargs) | ||||
|  | ||||
|         self.Post = Post | ||||
|         Post.drop_collection() | ||||
| @@ -237,63 +254,118 @@ class SignalTests(unittest.TestCase): | ||||
|  | ||||
|         self.assertEqual(self.get_signal_output(create_author), [ | ||||
|             "pre_init signal, Author", | ||||
|             "{'name': 'Bill Shakespeare'}", | ||||
|             {'name': 'Bill Shakespeare'}, | ||||
|             "post_init signal, Bill Shakespeare, document._created = True", | ||||
|         ]) | ||||
|  | ||||
|         a1 = self.Author(name='Bill Shakespeare') | ||||
|         self.assertEqual(self.get_signal_output(a1.save), [ | ||||
|             "pre_save signal, Bill Shakespeare", | ||||
|             {}, | ||||
|             "pre_save_post_validation signal, Bill Shakespeare", | ||||
|             "Is created", | ||||
|             {}, | ||||
|             "post_save signal, Bill Shakespeare", | ||||
|             "post_save dirty keys, ['name']", | ||||
|             "Is created" | ||||
|             "Is created", | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
|         a1.reload() | ||||
|         a1.name = 'William Shakespeare' | ||||
|         self.assertEqual(self.get_signal_output(a1.save), [ | ||||
|             "pre_save signal, William Shakespeare", | ||||
|             {}, | ||||
|             "pre_save_post_validation signal, William Shakespeare", | ||||
|             "Is updated", | ||||
|             {}, | ||||
|             "post_save signal, William Shakespeare", | ||||
|             "post_save dirty keys, ['name']", | ||||
|             "Is updated" | ||||
|             "Is updated", | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
|         self.assertEqual(self.get_signal_output(a1.delete), [ | ||||
|             'pre_delete signal, William Shakespeare', | ||||
|             {}, | ||||
|             'post_delete signal, William Shakespeare', | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
|         signal_output = self.get_signal_output(load_existing_author) | ||||
|         # test signal_output lines separately, because of random ObjectID after object load | ||||
|         self.assertEqual(signal_output[0], | ||||
|         self.assertEqual(self.get_signal_output(load_existing_author), [ | ||||
|             "pre_init signal, Author", | ||||
|         ) | ||||
|         self.assertEqual(signal_output[2], | ||||
|             "post_init signal, Bill Shakespeare, document._created = False", | ||||
|         ) | ||||
|             {'id': 2, 'name': 'Bill Shakespeare'}, | ||||
|             "post_init signal, Bill Shakespeare, document._created = False" | ||||
|         ]) | ||||
|  | ||||
|  | ||||
|         signal_output = self.get_signal_output(bulk_create_author_with_load) | ||||
|  | ||||
|         # The output of this signal is not entirely deterministic. The reloaded | ||||
|         # object will have an object ID. Hence, we only check part of the output | ||||
|         self.assertEqual(signal_output[3], "pre_bulk_insert signal, [<Author: Bill Shakespeare>]" | ||||
|         ) | ||||
|         self.assertEqual(signal_output[-2:], | ||||
|             ["post_bulk_insert signal, [<Author: Bill Shakespeare>]", | ||||
|              "Is loaded",]) | ||||
|         self.assertEqual(self.get_signal_output(bulk_create_author_with_load), [ | ||||
|             'pre_init signal, Author', | ||||
|             {'name': 'Bill Shakespeare'}, | ||||
|             'post_init signal, Bill Shakespeare, document._created = True', | ||||
|             'pre_bulk_insert signal, [<Author: Bill Shakespeare>]', | ||||
|             {}, | ||||
|             'pre_init signal, Author', | ||||
|             {'id': 3, 'name': 'Bill Shakespeare'}, | ||||
|             'post_init signal, Bill Shakespeare, document._created = False', | ||||
|             'post_bulk_insert signal, [<Author: Bill Shakespeare>]', | ||||
|             'Is loaded', | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
|         self.assertEqual(self.get_signal_output(bulk_create_author_without_load), [ | ||||
|             "pre_init signal, Author", | ||||
|             "{'name': 'Bill Shakespeare'}", | ||||
|             {'name': 'Bill Shakespeare'}, | ||||
|             "post_init signal, Bill Shakespeare, document._created = True", | ||||
|             "pre_bulk_insert signal, [<Author: Bill Shakespeare>]", | ||||
|             {}, | ||||
|             "post_bulk_insert signal, [<Author: Bill Shakespeare>]", | ||||
|             "Not loaded", | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
|     def test_signal_kwargs(self): | ||||
|         """ Make sure signal_kwargs is passed to signals calls. """ | ||||
|  | ||||
|         def live_and_let_die(): | ||||
|             a = self.Author(name='Bill Shakespeare') | ||||
|             a.save(signal_kwargs={'live': True, 'die': False}) | ||||
|             a.delete(signal_kwargs={'live': False, 'die': True}) | ||||
|  | ||||
|         self.assertEqual(self.get_signal_output(live_and_let_die), [ | ||||
|             "pre_init signal, Author", | ||||
|             {'name': 'Bill Shakespeare'}, | ||||
|             "post_init signal, Bill Shakespeare, document._created = True", | ||||
|             "pre_save signal, Bill Shakespeare", | ||||
|             {'die': False, 'live': True}, | ||||
|             "pre_save_post_validation signal, Bill Shakespeare", | ||||
|             "Is created", | ||||
|             {'die': False, 'live': True}, | ||||
|             "post_save signal, Bill Shakespeare", | ||||
|             "post_save dirty keys, ['name']", | ||||
|             "Is created", | ||||
|             {'die': False, 'live': True}, | ||||
|             'pre_delete signal, Bill Shakespeare', | ||||
|             {'die': True, 'live': False}, | ||||
|             'post_delete signal, Bill Shakespeare', | ||||
|             {'die': True, 'live': False} | ||||
|         ]) | ||||
|  | ||||
|         def bulk_create_author(): | ||||
|             a1 = self.Author(name='Bill Shakespeare') | ||||
|             self.Author.objects.insert([a1], signal_kwargs={'key': True}) | ||||
|  | ||||
|         self.assertEqual(self.get_signal_output(bulk_create_author), [ | ||||
|             'pre_init signal, Author', | ||||
|             {'name': 'Bill Shakespeare'}, | ||||
|             'post_init signal, Bill Shakespeare, document._created = True', | ||||
|             'pre_bulk_insert signal, [<Author: Bill Shakespeare>]', | ||||
|             {'key': True}, | ||||
|             'pre_init signal, Author', | ||||
|             {'id': 2, 'name': 'Bill Shakespeare'}, | ||||
|             'post_init signal, Bill Shakespeare, document._created = False', | ||||
|             'post_bulk_insert signal, [<Author: Bill Shakespeare>]', | ||||
|             'Is loaded', | ||||
|             {'key': True} | ||||
|         ]) | ||||
|  | ||||
|     def test_queryset_delete_signals(self): | ||||
| @@ -302,7 +374,9 @@ class SignalTests(unittest.TestCase): | ||||
|         self.Another(name='Bill Shakespeare').save() | ||||
|         self.assertEqual(self.get_signal_output(self.Another.objects.delete), [ | ||||
|             'pre_delete signal, Bill Shakespeare', | ||||
|             {}, | ||||
|             'post_delete signal, Bill Shakespeare', | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
|     def test_signals_with_explicit_doc_ids(self): | ||||
| @@ -353,7 +427,10 @@ class SignalTests(unittest.TestCase): | ||||
|         results = self.get_signal_output(bulk_set_active_post) | ||||
|         self.assertEqual(results, [ | ||||
|             "pre_bulk_insert signal, [(<Post: Post 1>, {'active': False}), (<Post: Post 2>, {'active': False}), (<Post: Post 3>, {'active': False})]", | ||||
|             "post_bulk_insert signal, [(<Post: Post 1>, {'active': True}), (<Post: Post 2>, {'active': True}), (<Post: Post 3>, {'active': True})]" | ||||
|             {}, | ||||
|             "post_bulk_insert signal, [(<Post: Post 1>, {'active': True}), (<Post: Post 2>, {'active': True}), (<Post: Post 3>, {'active': True})]", | ||||
|             'Is loaded', | ||||
|             {} | ||||
|         ]) | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|   | ||||
		Reference in New Issue
	
	Block a user