Permalink
Browse files

Fixing callables on model_mommy Recipe.

This commit addresses an issue with how callables were handled in model_mommy's
Recipe class. Previously, callables were detected and resolved on the `_make`
method of the Recipe class. This caused problems for things like the `_quantity`
api, since subsequent calls to mommy.make would just return the same value that
was first resolved in `_make`. If you tried to introduce randomness into your
mommy generations, you'd find this to be impossible via Recipe and _quantity.

We now pass callables straight through to `mommy.make`. There is new logic to
detect a callable and guarantee that is called each time make is called.

Additionally, a new test method has been introduced to ensure that the
`_quantity` is handled correctly.
  • Loading branch information...
1 parent 0b8a078 commit c7825f383c58bee2a766ce083d79b52360bcf762 @dencold dencold committed Oct 27, 2013
Showing with 11 additions and 2 deletions.
  1. +2 −0 model_mommy/mommy.py
  2. +0 −2 model_mommy/recipe.py
  3. +9 −0 test/generic/tests/test_recipes.py
View
@@ -277,6 +277,8 @@ def _make(self, commit=True, **attrs):
model_attrs[field.name] = self.generate_value(field)
elif isinstance(model_attrs[field.name], Sequence):
model_attrs[field.name] = model_attrs[field.name].gen(self.model)
+ elif callable(model_attrs[field.name]):
+ model_attrs[field.name] = model_attrs[field.name]()
return self.instance(model_attrs, _commit=commit)
View
@@ -18,8 +18,6 @@ def _mapping(self, new_attrs):
# do not generate values if field value is provided
if new_attrs.get(k):
continue
- if callable(v):
- mapping[k] = v()
elif isinstance(v, RecipeForeignKey):
a={}
for key, value in list(rel_fields_attrs.items()):
@@ -74,6 +74,15 @@ def test_always_calls_when_creating(self):
r.make().blank_char_field
self.assertEqual(choice_mock.call_count, 2)
+ def test_always_calls_with_quantity(self):
+ with patch('test.generic.tests.test_recipes.choice') as choice_mock:
+ l = ['foo', 'bar', 'spam', 'eggs']
+ r = Recipe(DummyBlankFieldsModel,
+ blank_char_field = lambda: choice(l)
+ )
+ r.make(_quantity=3)
+ self.assertEqual(choice_mock.call_count, 3)
+
def test_make_recipes_with_args(self):
"""
Overriding some fields values at recipe execution

0 comments on commit c7825f3

Please sign in to comment.