Skip to content

Commit

Permalink
[model-bakers#93] Add support for suffix in seq
Browse files Browse the repository at this point in the history
- This adds a new `suffix` keyword arg to the `seq` function to allow
  the concatenation of a common suffix string onto a generated `seq`
  value.
- This adds a section under "Sequences in recipes" to the documentation
  to provide example usage of the new keyword argument.
  - Additionally, an `email` field is added to the `Customer` example
    model in the README.md to go along with the new section in the
    documentation.
- This also adds unit tests for the new keyword argument behavior.
  • Loading branch information
timjk-gp committed Oct 2, 2020
1 parent 155f0cf commit da0c9ff
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pip install model_bakery
class Customer(models.Model):
enjoy_jards_macale = models.BooleanField()
name = models.CharField(max_length=30)
email = models.CharField(max_length=50)
age = models.IntegerField()
bio = models.TextField()
days_since_last_login = models.BigIntegerField()
Expand Down
18 changes: 18 additions & 0 deletions docs/source/recipes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,24 @@ Sometimes, you have a field with an unique value and using ``make`` can cause ra
This will append a counter to strings to avoid uniqueness problems and it will sum the counter with numerical values.

An optional ``suffix`` parameter can be supplied to augment the value for cases like generating emails
or other strings with common suffixes.

.. code-block:: python
>>> from model_bakery import.recipe import Recipe, seq
>>> from shop.models import Customer
>>> customer = Recipe(Customer, email=seq('user', suffix='@example.com'))
>>> customer = baker.make_recipe('shop.customer')
>>> customer.email
'user1@example.com'
>>> customer = baker.make_recipe('shop.customer')
>>> customer.email
'user2@example.com'
Sequences and iterables can be used not only for recipes, but with ``baker`` as well:

.. code-block:: python
Expand Down
4 changes: 2 additions & 2 deletions model_bakery/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def import_from_str(import_string):
return import_string


def seq(value, increment_by=1, start=None):
def seq(value, increment_by=1, start=None, suffix=None):
if type(value) in [datetime.datetime, datetime.date, datetime.time]:
if start:
msg = "start parameter is ignored when using seq with date, time or datetime objects"
Expand All @@ -46,4 +46,4 @@ def seq(value, increment_by=1, start=None):
yield series_date
else:
for n in itertools.count(start or increment_by, increment_by):
yield value + type(value)(n)
yield value + type(value)(n) + (suffix or type(value)())
25 changes: 25 additions & 0 deletions tests/test_recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,17 @@ def test_increment_for_strings(self):
person = baker.make_recipe("tests.generic.serial_person")
assert person.name == "joe3"

def test_increment_for_strings_with_suffix(self):
from model_bakery.recipe import seq # NoQA

fred_person = person_recipe.extend(name=seq("fred", suffix="@example.com"))
person = fred_person.make()
assert person.name == "fred1@example.com"
person = fred_person.make()
assert person.name == "fred2@example.com"
person = fred_person.make()
assert person.name == "fred3@example.com"

def test_increment_for_numbers(self):
dummy = baker.make_recipe("tests.generic.serial_numbers")
assert dummy.default_int_field == 11
Expand Down Expand Up @@ -442,6 +453,20 @@ def test_increment_for_numbers_2(self):
assert dummy.default_decimal_field == Decimal("23.1")
assert dummy.default_float_field == 4.23

def test_increment_for_numbers_with_suffix(self):
from model_bakery.recipe import seq # NoQA

dummy = baker.make_recipe(
"tests.generic.serial_numbers", default_int_field=seq(1, suffix=1)
)
assert dummy.default_int_field == 3

with pytest.raises(TypeError):
dummy = baker.make_recipe(
"tests.generic.serial_numbers",
default_int_field=seq(1, suffix="this should fail"),
)

def test_creates_unique_field_recipe_using_for_iterator(self):
for i in range(1, 4):
dummy = baker.make_recipe("tests.generic.dummy_unique_field")
Expand Down

0 comments on commit da0c9ff

Please sign in to comment.