diff options
author | Raphaël Barrois <raphael.barrois@polyconseil.fr> | 2011-05-16 14:48:23 +0200 |
---|---|---|
committer | Raphaël Barrois <raphael.barrois@polyconseil.fr> | 2011-05-16 14:48:23 +0200 |
commit | f7cb0a040cab507541405d64efbf44b874acf207 (patch) | |
tree | 54f7eb2603bb21ff5e5410a3b634e6261763cae0 /factory/containers.py | |
parent | df8b1e10e06a6a6faa15808caa7167f3a8361c55 (diff) | |
download | factory-boy-f7cb0a040cab507541405d64efbf44b874acf207.tar factory-boy-f7cb0a040cab507541405d64efbf44b874acf207.tar.gz |
Add SubFactories, and full testing.
Signed-off-by: Raphaël Barrois <raphael.barrois@polyconseil.fr>
Diffstat (limited to 'factory/containers.py')
-rw-r--r-- | factory/containers.py | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/factory/containers.py b/factory/containers.py index 63be161..8aa9955 100644 --- a/factory/containers.py +++ b/factory/containers.py @@ -18,7 +18,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from declarations import OrderedDeclaration +from declarations import OrderedDeclaration, SubFactory + + +ATTR_SPLITTER = '__' class ObjectParamsWrapper(object): '''A generic container that allows for getting but not setting of attributes. @@ -27,8 +30,8 @@ class ObjectParamsWrapper(object): initialized = False - def __init__(self, dict): - self.dict = dict + def __init__(self, attrs): + self.attrs = attrs self.initialized = True def __setattr__(self, name, value): @@ -39,7 +42,7 @@ class ObjectParamsWrapper(object): def __getattr__(self, name): try: - return self.dict[name] + return self.attrs[name] except KeyError: raise AttributeError("The param '{0}' does not exist. Perhaps your declarations are out of order?".format(name)) @@ -88,9 +91,12 @@ class OrderedDeclarationDict(object): class DeclarationsHolder(object): """Holds all declarations, ordered and unordered.""" - def __init__(self): + def __init__(self, defaults=None): + if not defaults: + defaults = {} self._ordered = OrderedDeclarationDict() self._unordered = {} + self.update_base(defaults) def update_base(self, attrs): """Updates the DeclarationsHolder from a class definition. @@ -119,10 +125,29 @@ class DeclarationsHolder(object): except KeyError: return self._ordered[key] - def build_attributes(self, factory, extra): + def iteritems(self): + for pair in self._unordered.iteritems(): + yield pair + for pair in self._ordered.iteritems(): + yield pair + + def items(self): + return list(self.iteritems()) + + def build_attributes(self, factory, create=False, extra=None): """Build the list of attributes based on class attributes.""" + if not extra: + extra = {} + attributes = {} - # For fields in _unordered, use the value from attrs if any; otherwise, + sub_fields = {} + for key in list(extra.keys()): + if ATTR_SPLITTER in key: + cls_name, attr_name = key.split(ATTR_SPLITTER, 1) + if cls_name in self: + sub_fields.setdefault(cls_name, {})[attr_name] = extra.pop(key) + + # For fields in _unordered, use the value from extra if any; otherwise, # use the default value. for key, value in self._unordered.iteritems(): attributes[key] = extra.get(key, value) @@ -130,8 +155,13 @@ class DeclarationsHolder(object): if key in extra: attributes[key] = extra[key] else: - wrapper = ObjectParamsWrapper(attributes) - attributes[key] = value.evaluate(factory, wrapper) + if isinstance(value, SubFactory): + new_value = value.evaluate(factory, create, + sub_fields.get(key, {})) + else: + wrapper = ObjectParamsWrapper(attributes) + new_value = value.evaluate(factory, wrapper) + attributes[key] = new_value attributes.update(extra) return attributes |