Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved list generation #1025

Open
hmvp opened this issue Jun 10, 2023 · 0 comments
Open

Improved list generation #1025

hmvp opened this issue Jun 10, 2023 · 0 comments

Comments

@hmvp
Copy link

hmvp commented Jun 10, 2023

The problem

We currently use a class (see next section) to generate random lists, with the option to override values on the items on that list.
I could not find functionality in factory_boy that matches this, however I feel that it would be very handy to have...

If this already exists I would really like to know how to do that ergonomically without a separate class...

Proposed solution

from typing import Any

import factory
from factory.random import randgen


class RandomListFactory(factory.SubFactory):
    def __init__(self, item_factory: factory.Factory, list_factory: str = "factory.ListFactory", **params: Any):
        self.item_factory = item_factory
        super().__init__(list_factory, **params)

    def evaluate(self, instance: Any, step: factory.base.builder.BuildStep, extra: dict[str, Any]) -> Any:
        size = extra.pop("size", None)
        min_items = size if (size is not None) else extra.pop("min", 1)
        max_items = size if (size is not None) else extra.pop("max", 15)
        for i in range(randgen.randint(min_items, max_items)):
            extra[str(i)] = factory.SubFactory(self.item_factory)

        return step.recurse(self.get_factory(), extra, force_sequence=step.sequence)


class GenerateMoneyFactory(factory.DictFactory):
    amount = factory.Faker("random_int")
    type = factory.Faker("random_element", elements=["Dollar", "Euro", "Rupee"])


class GeneratedWalletFactory(factory.DictFactory):
    contents = RandomListFactory(GenerateMoneyFactory)


wallet = GeneratedWalletFactory(contents__size=2, contents__0__amount=10, contents__1__type="Rupee")
print(wallet)  # prints: {'contents': [{'amount': 10, 'type': <random>}, {'amount': <random>, 'type': 'Rupee'}]}


wallet = GeneratedWalletFactory(contents__min=1, contents__max=3, contents__0__amount=10)
print(wallet)  # prints: {'contents': [{'amount': 10, 'type': <random>}, <random one or two extra items>]}

Extra notes

If you want to add this, feel free to improve it to make it more consistent with the rest of the code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant