Skip to content

Commit

Permalink
Feature/improve docs (#10)
Browse files Browse the repository at this point in the history
* Test examples.
* Improve TortoiseORM factories.
  • Loading branch information
barseghyanartur authored Dec 4, 2023
1 parent ade5068 commit b57bd3d
Show file tree
Hide file tree
Showing 22 changed files with 959 additions and 109 deletions.
6 changes: 3 additions & 3 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,16 @@
"filename": "Makefile",
"hashed_secret": "ee783f2421477b5483c23f47eca1f69a1f2bf4fb",
"is_verified": true,
"line_number": 59
"line_number": 71
},
{
"type": "Secret Keyword",
"filename": "Makefile",
"hashed_secret": "1457a35245051927fac6fa556074300f4162ed66",
"is_verified": true,
"line_number": 62
"line_number": 74
}
]
},
"generated_at": "2023-12-02T22:21:04Z"
"generated_at": "2023-12-03T22:23:51Z"
}
11 changes: 8 additions & 3 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,21 @@ For example:

**Good to know:**

- Test suite makes extensive use of parametrization. Make sure you have added
your changes in the right place.
- This library consists of a single ``fake.py`` module. That module is
dependency free, self-contained (includes all tests) and portable.
Do not submit pull requests splitting the ``fake.py`` module into small
parts.
- Some tests contain simplified implementation of existing libraries (Django
ORM). If you need to add integration tests for existing functionality,
you can add the relevant code and requirements to the examples.

**General list to go through:**

- Does your change require documentation update?
- Does your change require update to tests?
- Does your change rely on third-party package or a cloud based service?
If so, please consider turning it into a dedicated standalone package,
since this library is dependency free.
since this library is dependency free (and will always stay so).

**When fixing bugs (in addition to the general list):**

Expand Down
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,32 @@ install:
test:
source $(VENV) && pytest -vrx -s

django-test:
source $(VENV) && cd examples/django/ && ./manage.py test

pydantic-test:
source $(VENV) && cd examples/pydantic/ && python manage.py test

dataclasses-test:
source $(VENV) && cd examples/dataclasses/ && python manage.py test

tortoise-test:
source $(VENV) && cd examples/tortoise/ && python manage.py test

shell:
source $(VENV) && ipython

django-shell:
source $(VENV) && python examples/django/manage.py shell

pydantic-shell:
source $(VENV) && python examples/pydantic/shell.py
source $(VENV) && cd examples/pydantic/ && python manage.py shell

dataclasses-shell:
source $(VENV) && python examples/dataclasses/shell.py
source $(VENV) && cd examples/dataclasses/ && python manage.py shell

tortoise-shell:
source $(VENV) && python examples/tortoise/shell.py
source $(VENV) && cd examples/tortoise/ && python manage.py shell

create-secrets:
source $(VENV) && detect-secrets scan > .secrets.baseline
Expand Down
41 changes: 29 additions & 12 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ fake.py
.. External references
.. _Faker: https://faker.readthedocs.io/
.. _factory_boy: https://factoryboy.readthedocs.io/
.. _faker-file: https://faker-file.readthedocs.io/
.. _Pillow: https://python-pillow.org/
.. _dateutil: https://dateutil.readthedocs.io/
.. _Django: https://www.djangoproject.com/
.. _TortoiseORM: https://tortoise.github.io/
.. _Pydantic: https://docs.pydantic.dev/

.. Internal references
.. _fake.py: https://github.com/barseghyanartur/fake.py/
.. _Read the Docs: http://fakepy.readthedocs.io/
.. _Quick start: https://fakepy.readthedocs.io/en/latest/quick_start.html
.. _Recipes: https://fakepy.readthedocs.io/en/latest/recipes.html
Expand Down Expand Up @@ -44,12 +49,7 @@ Minimalistic, standalone alternative fake data generator with no dependencies.
:target: https://coveralls.io/github/barseghyanartur/fake.py?branch=main
:alt: Coverage

.. contents:: Table of Contents
:depth: 2

Overview
========
``fake.py`` is a standalone, portable library designed for generating various
`fake.py`_ is a standalone, portable library designed for generating various
random data types for testing.

It offers a simplified, dependency-free alternative for creating random
Expand Down Expand Up @@ -246,24 +246,41 @@ Tests

Run the tests with unittest:

.. code-block:: bash
.. code-block:: sh
python -m unittest
python -m unittest fake.py
Or pytest:

.. code-block:: bash
.. code-block:: sh
pytest
Differences with `Faker`_
=========================
``fake.py`` is modeled after the famous `Faker`_ package. Its' API is highly
Differences with alternatives
=============================
`fake.py`_ is `Faker`_ + `factory_boy`_ + `faker-file`_ in one package,
radically simplified and reduced in features, but without any external
dependencies (not even `Pillow`_ or `dateutil`_).

`fake.py`_ is modeled after the famous `Faker`_ package. Its' API is highly
compatible, although drastically reduced. It's not multilingual and does not
support postal codes or that many RAW file formats. However, you could easily
include it in your production setup without worrying about yet another
dependency.

On the other hand, `fake.py`_ factories look quite similar to `factory_boy`_
factories, although again - drastically simplified and reduced in
features.

The file generation part of `fake.py`_ are modelled after the `faker-file`_.
You don't get a large variety of file types supported and you don't have that
much control over the content of the files generated, but you get
dependency-free valid files and if that's all you need, you don't need to look
further.

However, at any point, if you discover that you "need more", go for `Faker`_,
`factory_boy`_ and `faker-file`_ combination.

License
=======

Expand Down
6 changes: 3 additions & 3 deletions docs/creating_images.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Creating images
.. _faker-file: https://pypi.org/project/faker-file/

Creating images could be a challenging task. The goal of this library
is to help you out with basic tasks. You can easily generate very basic
graphic images, but no custom shapes. Paper size is A4.
Creating images for testing could be a challenging job. The goal of this
library is to help you out with basic tasks. You can easily generate very
basic graphic images, but no custom shapes. Paper size is A4.

If you don't like how image files are generated by this library, you can
check the `faker-file`_ package, which can produce complex images.
Expand Down
135 changes: 130 additions & 5 deletions docs/factories.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ Django example
from article.models import Article
# For Django, all files shall be placed inside `MEDIA_ROOT` directory.
# That's why you need to apply this trick - define a
# custom `FileSystemStorage` class and pass it to the file factory as
# `storage` argument.
STORAGE = FileSystemStorage(root_path=settings.MEDIA_ROOT, rel_path="tmp")
class UserFactory(DjangoModelFactory):
username = FACTORY.username()
Expand All @@ -66,7 +69,6 @@ Django example
def __set_password(instance):
instance.set_password("test")
class ArticleFactory(DjangoModelFactory):
title = FACTORY.sentence()
Expand All @@ -81,7 +83,6 @@ Django example
class Meta:
model = Article
**Usage example**

.. code-block:: python
Expand All @@ -97,6 +98,46 @@ Django example
Pydantic example
----------------
**article/models.py**

.. code-block:: python
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field
class User(BaseModel):
id: int
username: str = Field(..., max_length=255)
first_name: str = Field(..., max_length=255)
last_name: str = Field(..., max_length=255)
email: str = Field(..., max_length=255)
password: Optional[str] = Field("", max_length=255)
last_login: Optional[datetime]
is_superuser: bool = Field(default=False)
is_staff: bool = Field(default=False)
is_active: bool = Field(default=True)
date_joined: Optional[datetime]
def __str__(self):
return self.username
class Article(BaseModel):
id: int
title: str = Field(..., max_length=255)
slug: str = Field(..., max_length=255, unique=True)
content: str
image: Optional[str] = None # Use str to represent the image path or URL
pub_date: datetime = Field(default_factory=datetime.now)
safe_for_work: bool = False
minutes_to_read: int = 5
author: User
def __str__(self):
return self.title
**article/factories.py**

.. code-block:: python
Expand Down Expand Up @@ -145,6 +186,49 @@ Pydantic example
TortoiseORM example
-------------------

**article/models.py**

.. code-block:: python
from datetime import datetime
from tortoise import fields
from tortoise.models import Model
class User(Model):
id = fields.IntField(pk=True)
username = fields.CharField(max_length=255, unique=True)
first_name = fields.CharField(max_length=255)
last_name = fields.CharField(max_length=255)
email = fields.CharField(max_length=255)
password = fields.CharField(max_length=255, null=True, blank=True)
last_login = fields.DatetimeField(null=True, blank=True)
is_superuser = fields.BooleanField(default=False)
is_staff = fields.BooleanField(default=False)
is_active = fields.BooleanField(default=True)
date_joined = fields.DatetimeField(null=True, blank=True)
def __str__(self):
return self.title
class Article(Model):
id = fields.IntField(pk=True)
title = fields.CharField(max_length=255)
slug = fields.CharField(max_length=255, unique=True)
content = fields.TextField()
image = fields.TextField(null=True, blank=True)
pub_date = fields.DatetimeField(default=datetime.now)
safe_for_work = fields.BooleanField(default=False)
minutes_to_read = fields.IntField(default=5)
author = fields.ForeignKeyField("models.User", on_delete=fields.CASCADE)
def __str__(self):
return self.title
**article/factories.py**

.. code-block:: python
from pathlib import Path
Expand All @@ -161,7 +245,6 @@ TortoiseORM example
class UserFactory(TortoiseModelFactory):
"""User factory."""
# id = FACTORY.pyint()
username = FACTORY.username()
first_name = FACTORY.first_name()
last_name = FACTORY.last_name()
Expand All @@ -179,7 +262,6 @@ TortoiseORM example
class ArticleFactory(TortoiseModelFactory):
"""Article factory."""
# id = FACTORY.pyint()
title = FACTORY.sentence()
slug = FACTORY.slug()
content = FACTORY.text()
Expand All @@ -196,6 +278,49 @@ TortoiseORM example

Dataclasses example
-------------------

**article/models.py**

.. code-block:: python
from dataclasses import dataclass
from datetime import datetime
from typing import Optional
@dataclass
class User:
id: int
username: str
first_name: str
last_name: str
email: str
last_login: Optional[datetime]
date_joined: Optional[datetime]
password: Optional[str] = None
is_superuser: bool = False
is_staff: bool = False
is_active: bool = True
def __str__(self):
return self.username
@dataclass
class Article:
id: int
title: str
slug: str
content: str
author: User
image: Optional[str] = None # Use str to represent the image path or URL
pub_date: datetime = datetime.now()
safe_for_work: bool = False
minutes_to_read: int = 5
def __str__(self):
return self.title
**article/factories.py**

.. code-block:: python
from pathlib import Path
Expand Down
Loading

0 comments on commit b57bd3d

Please sign in to comment.