From 689b06c59788dedfce0af444760a3e5966761016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Barrois?= Date: Fri, 15 Nov 2013 20:19:51 +0100 Subject: Rename README. Let's keep github happy... --- MANIFEST.in | 2 +- README | 277 ----------------------------------------------------------- README.rst | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 278 insertions(+), 279 deletions(-) delete mode 100644 README mode change 120000 => 100644 README.rst diff --git a/MANIFEST.in b/MANIFEST.in index 3f09bc6..3dfc1be 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include README +include README.rst include docs/Makefile recursive-include docs *.py *.rst include docs/_static/.keep_dir diff --git a/README b/README deleted file mode 100644 index 0371b28..0000000 --- a/README +++ /dev/null @@ -1,277 +0,0 @@ -factory_boy -=========== - -.. image:: https://secure.travis-ci.org/rbarrois/factory_boy.png?branch=master - :target: http://travis-ci.org/rbarrois/factory_boy/ - -factory_boy is a fixtures replacement based on thoughtbot's `factory_girl `_. - -Its features include: - -- Straightforward syntax -- Support for multiple build strategies (saved/unsaved instances, attribute dicts, stubbed objects) -- Powerful helpers for common cases (sequences, sub-factories, reverse dependencies, circular factories, ...) -- Multiple factories per class support, including inheritance -- Support for various ORMs (currently Django, Mogo, SQLAlchemy) - - -Links ------ - -* Documentation: http://factoryboy.readthedocs.org/ -* Official repository: https://github.com/rbarrois/factory_boy -* Package: https://pypi.python.org/pypi/factory_boy/ - -factory_boy supports Python 2.6, 2.7, 3.2 and 3.3, as well as PyPy; it requires only the standard Python library. - - -Download --------- - -PyPI: https://pypi.python.org/pypi/factory_boy/ - -.. code-block:: sh - - $ pip install factory_boy - -Source: https://github.com/rbarrois/factory_boy/ - -.. code-block:: sh - - $ git clone git://github.com/rbarrois/factory_boy/ - $ python setup.py install - - -Usage ------ - - -.. note:: This section provides a quick summary of factory_boy features. - A more detailed listing is available in the full documentation. - - -Defining factories -"""""""""""""""""" - -Factories declare a set of attributes used to instantiate an object. The class of the object must be defined in the FACTORY_FOR attribute: - -.. code-block:: python - - import factory - from . import models - - class UserFactory(factory.Factory): - FACTORY_FOR = models.User - - first_name = 'John' - last_name = 'Doe' - admin = False - - # Another, different, factory for the same object - class AdminFactory(factory.Factory): - FACTORY_FOR = models.User - - first_name = 'Admin' - last_name = 'User' - admin = True - - -Using factories -""""""""""""""" - -factory_boy supports several different build strategies: build, create, attributes and stub: - -.. code-block:: python - - # Returns a User instance that's not saved - user = UserFactory.build() - - # Returns a saved User instance - user = UserFactory.create() - - # Returns a dict of attributes that can be used to build a User instance - attributes = UserFactory.attributes() - - -You can use the Factory class as a shortcut for the default build strategy: - -.. code-block:: python - - # Same as UserFactory.create() - user = UserFactory() - - -No matter which strategy is used, it's possible to override the defined attributes by passing keyword arguments: - -.. code-block:: pycon - - # Build a User instance and override first_name - >>> user = UserFactory.build(first_name='Joe') - >>> user.first_name - "Joe" - - -Lazy Attributes -""""""""""""""" - -Most factory attributes can be added using static values that are evaluated when the factory is defined, -but some attributes (such as fields whose value is computed from other elements) -will need values assigned each time an instance is generated. - -These "lazy" attributes can be added as follows: - -.. code-block:: python - - class UserFactory(factory.Factory): - FACTORY_FOR = models.User - first_name = 'Joe' - last_name = 'Blow' - email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower()) - -.. code-block:: pycon - - >>> UserFactory().email - "joe.blow@example.com" - - -Sequences -""""""""" - -Unique values in a specific format (for example, e-mail addresses) can be generated using sequences. Sequences are defined by using ``Sequence`` or the decorator ``sequence``: - -.. code-block:: python - - class UserFactory(factory.Factory): - FACTORY_FOR = models.User - email = factory.Sequence(lambda n: 'person{0}@example.com'.format(n)) - - >>> UserFactory().email - 'person0@example.com' - >>> UserFactory().email - 'person1@example.com' - - -Associations -"""""""""""" - -Some objects have a complex field, that should itself be defined from a dedicated factories. -This is handled by the ``SubFactory`` helper: - -.. code-block:: python - - class PostFactory(factory.Factory): - FACTORY_FOR = models.Post - author = factory.SubFactory(UserFactory) - - -The associated object's strategy will be used: - - -.. code-block:: python - - # Builds and saves a User and a Post - >>> post = PostFactory() - >>> post.id is None # Post has been 'saved' - False - >>> post.author.id is None # post.author has been saved - False - - # Builds but does not save a User, and then builds but does not save a Post - >>> post = PostFactory.build() - >>> post.id is None - True - >>> post.author.id is None - True - - -Debugging factory_boy -""""""""""""""""""""" - -Debugging factory_boy can be rather complex due to the long chains of calls. -Detailed logging is available through the ``factory`` logger. - -A helper, :meth:`factory.debug()`, is available to ease debugging: - -.. code-block:: python - - with factory.debug(): - obj = TestModel2Factory() - - - import logging - logger = logging.getLogger('factory') - logger.addHandler(logging.StreamHandler()) - logger.setLevel(logging.DEBUG) - -This will yield messages similar to those (artificial indentation): - -.. code-block:: ini - - BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={}) - LazyStub: Computing values for tests.test_using.TestModel2Factory(two=>) - SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(,), one=4), create=True - BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (,), 'one': 4}) - LazyStub: Computing values for tests.test_using.TestModelFactory(one=4) - LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4) - BaseFactory: Generating tests.test_using.TestModelFactory(one=4) - LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=) - BaseFactory: Generating tests.test_using.TestModel2Factory(two=) - - -ORM Support -""""""""""" - -factory_boy has specific support for a few ORMs, through specific :class:`~factory.Factory` subclasses: - -* Django, with :class:`~factory.django.DjangoModelFactory` -* Mogo, with :class:`~factory.mogo.MogoFactory` -* MongoEngine, with :class:`~factory.mongoengine.MongoEngineFactory` -* SQLAlchemy, with :class:`~factory.alchemy.SQLAlchemyModelFactory` - -Contributing ------------- - -factory_boy is distributed under the MIT License. - -Issues should be opened through `GitHub Issues `_; whenever possible, a pull request should be included. - -All pull request should pass the test suite, which can be launched simply with: - -.. code-block:: sh - - $ python setup.py test - - -.. note:: - - Running test requires the unittest2 (standard in Python 2.7+) and mock libraries. - - -In order to test coverage, please use: - -.. code-block:: sh - - $ pip install coverage - $ coverage erase; coverage run --branch setup.py test; coverage report - - -Contents, indices and tables ----------------------------- - -.. toctree:: - :maxdepth: 2 - - introduction - reference - orms - recipes - fuzzy - examples - internals - changelog - ideas - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/README.rst b/README.rst deleted file mode 120000 index 100b938..0000000 --- a/README.rst +++ /dev/null @@ -1 +0,0 @@ -README \ No newline at end of file diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..0371b28 --- /dev/null +++ b/README.rst @@ -0,0 +1,277 @@ +factory_boy +=========== + +.. image:: https://secure.travis-ci.org/rbarrois/factory_boy.png?branch=master + :target: http://travis-ci.org/rbarrois/factory_boy/ + +factory_boy is a fixtures replacement based on thoughtbot's `factory_girl `_. + +Its features include: + +- Straightforward syntax +- Support for multiple build strategies (saved/unsaved instances, attribute dicts, stubbed objects) +- Powerful helpers for common cases (sequences, sub-factories, reverse dependencies, circular factories, ...) +- Multiple factories per class support, including inheritance +- Support for various ORMs (currently Django, Mogo, SQLAlchemy) + + +Links +----- + +* Documentation: http://factoryboy.readthedocs.org/ +* Official repository: https://github.com/rbarrois/factory_boy +* Package: https://pypi.python.org/pypi/factory_boy/ + +factory_boy supports Python 2.6, 2.7, 3.2 and 3.3, as well as PyPy; it requires only the standard Python library. + + +Download +-------- + +PyPI: https://pypi.python.org/pypi/factory_boy/ + +.. code-block:: sh + + $ pip install factory_boy + +Source: https://github.com/rbarrois/factory_boy/ + +.. code-block:: sh + + $ git clone git://github.com/rbarrois/factory_boy/ + $ python setup.py install + + +Usage +----- + + +.. note:: This section provides a quick summary of factory_boy features. + A more detailed listing is available in the full documentation. + + +Defining factories +"""""""""""""""""" + +Factories declare a set of attributes used to instantiate an object. The class of the object must be defined in the FACTORY_FOR attribute: + +.. code-block:: python + + import factory + from . import models + + class UserFactory(factory.Factory): + FACTORY_FOR = models.User + + first_name = 'John' + last_name = 'Doe' + admin = False + + # Another, different, factory for the same object + class AdminFactory(factory.Factory): + FACTORY_FOR = models.User + + first_name = 'Admin' + last_name = 'User' + admin = True + + +Using factories +""""""""""""""" + +factory_boy supports several different build strategies: build, create, attributes and stub: + +.. code-block:: python + + # Returns a User instance that's not saved + user = UserFactory.build() + + # Returns a saved User instance + user = UserFactory.create() + + # Returns a dict of attributes that can be used to build a User instance + attributes = UserFactory.attributes() + + +You can use the Factory class as a shortcut for the default build strategy: + +.. code-block:: python + + # Same as UserFactory.create() + user = UserFactory() + + +No matter which strategy is used, it's possible to override the defined attributes by passing keyword arguments: + +.. code-block:: pycon + + # Build a User instance and override first_name + >>> user = UserFactory.build(first_name='Joe') + >>> user.first_name + "Joe" + + +Lazy Attributes +""""""""""""""" + +Most factory attributes can be added using static values that are evaluated when the factory is defined, +but some attributes (such as fields whose value is computed from other elements) +will need values assigned each time an instance is generated. + +These "lazy" attributes can be added as follows: + +.. code-block:: python + + class UserFactory(factory.Factory): + FACTORY_FOR = models.User + first_name = 'Joe' + last_name = 'Blow' + email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower()) + +.. code-block:: pycon + + >>> UserFactory().email + "joe.blow@example.com" + + +Sequences +""""""""" + +Unique values in a specific format (for example, e-mail addresses) can be generated using sequences. Sequences are defined by using ``Sequence`` or the decorator ``sequence``: + +.. code-block:: python + + class UserFactory(factory.Factory): + FACTORY_FOR = models.User + email = factory.Sequence(lambda n: 'person{0}@example.com'.format(n)) + + >>> UserFactory().email + 'person0@example.com' + >>> UserFactory().email + 'person1@example.com' + + +Associations +"""""""""""" + +Some objects have a complex field, that should itself be defined from a dedicated factories. +This is handled by the ``SubFactory`` helper: + +.. code-block:: python + + class PostFactory(factory.Factory): + FACTORY_FOR = models.Post + author = factory.SubFactory(UserFactory) + + +The associated object's strategy will be used: + + +.. code-block:: python + + # Builds and saves a User and a Post + >>> post = PostFactory() + >>> post.id is None # Post has been 'saved' + False + >>> post.author.id is None # post.author has been saved + False + + # Builds but does not save a User, and then builds but does not save a Post + >>> post = PostFactory.build() + >>> post.id is None + True + >>> post.author.id is None + True + + +Debugging factory_boy +""""""""""""""""""""" + +Debugging factory_boy can be rather complex due to the long chains of calls. +Detailed logging is available through the ``factory`` logger. + +A helper, :meth:`factory.debug()`, is available to ease debugging: + +.. code-block:: python + + with factory.debug(): + obj = TestModel2Factory() + + + import logging + logger = logging.getLogger('factory') + logger.addHandler(logging.StreamHandler()) + logger.setLevel(logging.DEBUG) + +This will yield messages similar to those (artificial indentation): + +.. code-block:: ini + + BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={}) + LazyStub: Computing values for tests.test_using.TestModel2Factory(two=>) + SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(,), one=4), create=True + BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (,), 'one': 4}) + LazyStub: Computing values for tests.test_using.TestModelFactory(one=4) + LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4) + BaseFactory: Generating tests.test_using.TestModelFactory(one=4) + LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=) + BaseFactory: Generating tests.test_using.TestModel2Factory(two=) + + +ORM Support +""""""""""" + +factory_boy has specific support for a few ORMs, through specific :class:`~factory.Factory` subclasses: + +* Django, with :class:`~factory.django.DjangoModelFactory` +* Mogo, with :class:`~factory.mogo.MogoFactory` +* MongoEngine, with :class:`~factory.mongoengine.MongoEngineFactory` +* SQLAlchemy, with :class:`~factory.alchemy.SQLAlchemyModelFactory` + +Contributing +------------ + +factory_boy is distributed under the MIT License. + +Issues should be opened through `GitHub Issues `_; whenever possible, a pull request should be included. + +All pull request should pass the test suite, which can be launched simply with: + +.. code-block:: sh + + $ python setup.py test + + +.. note:: + + Running test requires the unittest2 (standard in Python 2.7+) and mock libraries. + + +In order to test coverage, please use: + +.. code-block:: sh + + $ pip install coverage + $ coverage erase; coverage run --branch setup.py test; coverage report + + +Contents, indices and tables +---------------------------- + +.. toctree:: + :maxdepth: 2 + + introduction + reference + orms + recipes + fuzzy + examples + internals + changelog + ideas + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + -- cgit v1.2.3