Commits

ol...@ollycope.com  committed 3838dd8

Added more options for setting factoryoptions

  • Participants
  • Parent commits 964b59f

Comments (0)

Files changed (2)

File test_toffee.py

             expect(f.bar.foo.name) == 'thing2'
 
 
+class TestFactoryOptions(object):
+
+    def test_can_set_factory_in_fixture_class(self):
+        class fixture(Fixture):
+            factoryoptions = {'foo': 'bar'}
+            F = Factory(object)
+
+        with fixture() as f:
+            expect(f.factoryoptions) == {'foo': 'bar'}
+
+    def test_can_set_factory_in_fixture_init(self):
+        class fixture(Fixture):
+            factoryoptions = {'foo': 'bar'}
+            F = Factory(object)
+
+        with Fixture(factoryoptions={'foo': 'bar'}) as f:
+            expect(f.factoryoptions) == {'foo': 'bar'}
+
+    def test_factoryoptions_are_independent_between_runs(self):
+
+        with Fixture(factoryoptions={'foo': 'bar'}) as f:
+            expect(f.factoryoptions) == {'foo': 'bar'}
+
+        with Fixture(factoryoptions={'bar': 'foo'}) as f:
+            expect(f.factoryoptions) == {'bar': 'foo'}
+
+    def test_factoryoptions_are_reset_to_class_defaults(self):
+
+        class fixture(Fixture):
+            factoryoptions = {'fish': 'chips'}
+
+        with fixture(factoryoptions={'fish': 'fingers'}) as f:
+            expect(f.factoryoptions) == {'fish': 'fingers'}
+
+        with fixture() as f:
+            expect(f.factoryoptions) == {'fish': 'chips'}
+
+
 class TestStormFactory(object):
 
     def setup(self):
         return ob
 
     @classmethod
+    def configure(cls):
+        """\
+        Return a dynamically created Factory subclass.
+
+        In the Factory base class this serves no functional purpose, however
+        subclasses may extend this to provide configuration points.
+        For example :class:`~toffee.StormFactory` uses this to allow the user
+        to supply the getstore method.
+        """
+        return type(cls.__name__, (cls,), {})
+
+    @classmethod
     def setup_complete(self, context, created):
         """\
         Override this in subclasses to implement custom behaviour after all
         fixture.setup(flush=False)
         fixture.setup(commit=True)
 
+    Alternatively you can supply factory options in the fixture class:
+
+        class fixture(Fixture):
+            factoryoptions = {'commit': True}
+
     """
 
     #: Callable that can retrieve Storm's store object.
 
     storekey = '_StormFactory_store'
 
+    default_flush = True
+    default_commit = False
+
     @classmethod
-    def configure(cls, getstore):
-        return type('StormFactory', (StormFactory,),
+    def configure(cls, getstore, *args, **kwargs):
+        base = super(StormFactory, cls).configure(*args, **kwargs)
+        return type(cls.__name__, (base,),
                     {'getstore': staticmethod(getstore)})
 
     @classmethod
     def setup_complete(cls, context, created):
         store = cls._getstore_cached(context)
         if store:
-            if context.factoryoptions.get('flush', True):
+            if context.factoryoptions.get('flush', cls.default_flush):
                 store.flush()
-            if context.factoryoptions.get('commit', False):
+            if context.factoryoptions.get('commit', cls.default_commit):
                 store.commit()
 
     @classmethod
     def teardown_complete(cls, context, created):
         store = cls._getstore_cached(context)
         if store:
-            if context.factoryoptions.get('flush', True):
+            if context.factoryoptions.get('flush', cls.default_flush):
                 store.flush()
-            if context.factoryoptions.get('commit', False):
+            if context.factoryoptions.get('commit', cls.default_commit):
                 store.commit()
 
 
 
 class Fixture(object):
 
+    #: Default factory options. See :class:`~toffee.StormFactory` for an
+    #: example of how these are used to control flush and commit options.
+    factoryoptions = {}
+
     def __init__(self, **kwargs):
 
         #: Factory definitions
         self.o = AttrDict()
         self.created = None
 
+        self.factoryoptions_defaults = self.factoryoptions.copy()
+        self.factoryoptions_defaults.update(kwargs.pop('factoryoptions', {}))
+
         class_factories = ((k, getattr(self.__class__, k))
                            for k in dir(self.__class__))
         class_factories = ((k, v)
             raise Exception("setup() has already been called on this fixture. "
                             "Call teardown first, or use setup(force=True).")
 
-        self.factoryoptions = factoryoptions
+        self.factoryoptions = dict(self.factoryoptions_defaults,
+                                   **factoryoptions)
         self.o = AttrDict()
         self.created = []
         self.argument_generators = {}