Commits

Anonymous committed d68668e

StormFactory now flushes/commits on teardown as well as setup

This means the store is left clean for subsequent operations

Comments (0)

Files changed (3)

 CHANGELOG
 =========
 
+Version 0.1.1
+
+- Bugfix: StormFactory did not flush/commit the store on fixture teardown
+  teardown, meaning the store would not be left clean for subsequent operations
+
 Version 0.1
 
 - initial release
         self.store.remove.assert_called_once_with(0)
 
     def test_it_doesnt_commit_by_default(self):
-        Fixture(x=self.factory(int)).setup()
+        f = Fixture(x=self.factory(int)).setup()
+        assert self.store.commit.called is False
+        f.teardown()
         assert self.store.commit.called is False
 
     def test_it_commits_if_requested(self):
-        Fixture(x=self.factory(int)).setup(commit=True)
-        assert self.store.commit.called is True
+        f = Fixture(x=self.factory(int)).setup(commit=True)
+        assert self.store.commit.call_count == 1
+        f.teardown()
+        assert self.store.commit.call_count == 2
 
     def test_it_flushes_by_default(self):
-        Fixture(x=self.factory(int)).setup()
-        assert self.store.flush.called is True
+        f = Fixture(x=self.factory(int)).setup()
+        assert self.store.flush.call_count == 1
+        f.teardown()
+        assert self.store.flush.call_count == 2
 
     def test_it_doesnt_flushes_if_requested(self):
-        Fixture(x=self.factory(int)).setup(flush=False)
+        f = Fixture(x=self.factory(int)).setup(flush=False)
+        assert self.store.flush.called is False
+        f.teardown()
         assert self.store.flush.called is False
 
 
         objects have been created (eg flushing to database)
         """
 
+    @classmethod
+    def teardown_complete(self, context, created):
+        """\
+        Override this in subclasses to implement custom behaviour after all
+        objects have been torn down (eg flushing to database)
+        """
+
 
 class CallFactory(Factory):
     """\
             if context.factoryoptions.get('commit', False):
                 store.commit()
 
+    @classmethod
+    def teardown_complete(cls, context, created):
+        store = cls._getstore_cached(context)
+        if store:
+            if context.factoryoptions.get('flush', True):
+                store.flush()
+            if context.factoryoptions.get('commit', False):
+                store.commit()
+
 
 class ArgumentGenerator(object):
     """
 
         self.configure()
 
+    def teardown_complete(self, torndown):
+        """\
+        Call any teardown_complete methods on factory classes to let them know
+        that all objects have been torn down
+        """
+        factory_created = {}
+
+        for name, ob, factory in torndown:
+            factory_created.setdefault(factory.__class__, []).append(ob)
+
+        for f, obs in factory_created.items():
+            f.teardown_complete(self, obs)
+
     def configure(self):
         """\
         Subclasses should override this to provide custom post-creation
         return what
 
     def teardown(self):
+        torndown = []
         while self.created:
             name, ob, factory = self.created.pop()
             if name is not None:
                 del self.o[name]
             factory.destroy_object(self, ob)
+            torndown.append((name, ob, factory))
+        self.teardown_complete(torndown)
         self.factoryoptions = {}
 
     def __enter__(self, *args, **kwargs):