Skip to content

Commit

Permalink
Merge pull request #655 from chinapandaman/PPF-615
Browse files Browse the repository at this point in the history
PPF-615: create developer guide docs
  • Loading branch information
chinapandaman authored Jun 17, 2024
2 parents 6f7bdda + d0dc119 commit dc4a062
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 1 deletion.
25 changes: 25 additions & 0 deletions docs/dev_changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Pull Request Requirements

Whenever a pull request is submitted, there are some expectations for the content before it can be merged
into the master branch.

## Code changes

There isn't any strict rule on how coding should be done for PyPDFForm. The project welcomes code contributions from
anyone with any level of expertise.

With that said, there are some conventions that are expected to be followed by your PR:

* Your changes must pass [Pylint](https://www.pylint.org/). To check if this is true, simply run `pylint PyPDFForm`.
* Your changes must pass all tests and have 100% coverage. You can read more about testing [here](dev_test.md).
* If you are changing the user APIs or any other parts of the code that are relevant, please update the appropriate documentation too.

## Merge process

Your PR will be reviewed before merging into the master branch. On top of that, it needs to run through some CI checks:

* Pylint on the source code.
* Tests will be run on three mainstream operating systems: `ubuntu`, `windows`, and `macos`, and across all Python versions the library supports on each OS.

Once the CI is green and your code looks good, the PR will be merged into the master branch. After every PR merge, [black](https://black.readthedocs.io/) and
[isort](https://pycqa.github.io/isort/) will be run on your code, and they will be deployed on the next release.
12 changes: 12 additions & 0 deletions docs/dev_doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Hosting Docs Locally

When the changes apply to the user APIs or any other parts of the code that are relevant, the appropriate documentation should
also be updated.

PyPDFForm uses [MkDocs](https://www.mkdocs.org/) for building the documentation. To host the doc site locally, simply run:

```shell
mkdocs serve
```

And you will find the doc site at `http://127.0.0.1:8000/`.
34 changes: 34 additions & 0 deletions docs/dev_intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Developer Intro

PyPDFForm's targeted users are other Python developers. This section of the documentation is not for the users,
but for people who want to start making contributions to PyPDFForm itself.

## Installing requirements

It is advised that a virtual environment is created before running this command:

```shell
pip install -r requirements.txt
```

## Running tests

See [testing PyPDFForm with pytest](dev_test.md).

## Creating issues

When you create an issue on GitHub, try your best to follow these conventions:

* The issue title should have the format `PPF-<issue number>: <title of the issue>`.
* The issue description should be as descriptive as possible, preferably with the following:
* A code snippet related to the issue.
* A PDF form template used by the code snippet.
* Screenshots that can help visualize the issue.

## Opening pull requests

Please create an issue before making a pull request. Try your best to follow these conventions when doing so:

* The PR title should be the same as its respective issue, so `PPF-<issue number>: <title of the issue>`.
* The PR description should contain a brief explanation of the changes.
* Once opened, the PR should be linked to its respective issue.
23 changes: 23 additions & 0 deletions docs/dev_release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Releasing

A PyPDFForm release starts with the following steps:

* A release [issue](https://github.com/chinapandaman/PyPDFForm/issues/646) and [PR](https://github.com/chinapandaman/PyPDFForm/pull/647).
* A new [GitHub release](https://github.com/chinapandaman/PyPDFForm/releases) with auto-generated changelogs.

Once these steps are done, the CI for deployment will be triggered.

## Deploy process

When the GitHub release is created, it will trigger two different CIs:

* [Deploy](https://github.com/chinapandaman/PyPDFForm/actions/workflows/python-publish.yml), which will create the distribution and upload it to [PyPI](https://pypi.org/project/PyPDFForm/).
* [Deploy Docs](https://github.com/chinapandaman/PyPDFForm/actions/workflows/deploy-docs.yml), which will tear down and rebuild the [GitHub page](https://chinapandaman.github.io/PyPDFForm/) where the doc site is hosted.

## When are releases done?

It depends on the changes that are currently on the master branch but have not deployed yet. Generally speaking:

* Serious bugs are usually released immediately after they are fixed.
* New features can usually wait and are released on a weekly basis.
* Trivial changes are usually bundled with other changes and can wait indefinitely.
95 changes: 95 additions & 0 deletions docs/dev_test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Testing

PyPDFForm uses [pytest](https://pytest.org/) for testing and [coverage.py](https://coverage.readthedocs.io/)
for test coverages. Tests can be run by simply executing:

```shell
coverage run -m pytest && coverage report --fail-under=100
```

## Generate coverage report

To generate a coverage report, run:

```shell
coverage run -m pytest && coverage html
```

And the coverage report can be viewed by opening `htmlcov/index.html` in a browser.

## Test breakdown

Each PyPDFForm test is different. However, there is a general paradigm that almost all tests follow.

In most cases, a test can be verbally summed up into three steps:

* Define an expected PDF file that the outcome of the test should look like.
* Execute a sequence of code using PyPDFForm to generate a PDF that should look like the expected PDF file.
* Compare the PDF generated by the test with the expected PDF file.

Consider this example test:

```python
def test_fill(pdf_samples, request):
expected_path = os.path.join(pdf_samples, "sample_filled.pdf")
with open(expected_path, "rb+") as f:
obj = PdfWrapper(
os.path.join(pdf_samples, "sample_template.pdf")
).fill(
{
"test": "test_1",
"check": True,
"test_2": "test_2",
"check_2": False,
"test_3": "test_3",
"check_3": True,
},
)

request.config.results["expected_path"] = expected_path
request.config.results["stream"] = obj.read()

expected = f.read()

assert len(obj.read()) == len(expected)
assert obj.read() == expected
```

The test starts by defining an expected PDF `sample_filled.pdf`:

```python
expected_path = os.path.join(pdf_samples, "sample_filled.pdf")
```

The test then fills `sample_template.pdf` with a data dictionary using `PdfWrapper`:

```python
obj = PdfWrapper(
os.path.join(pdf_samples, "sample_template.pdf")
).fill(
{
"test": "test_1",
"check": True,
"test_2": "test_2",
"check_2": False,
"test_3": "test_3",
"check_3": True,
},
)
```

These two lines should almost always be included in every test to make updating old tests easier:

```python
request.config.results["expected_path"] = expected_path
request.config.results["stream"] = obj.read()
```

Finally, the test compares the resulted stream from the test with the expected file stream:

```python
expected = f.read()

assert len(obj.read()) == len(expected)
assert obj.read() == expected
```
2 changes: 1 addition & 1 deletion docs/fill.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

PyPDFForm uses a single depth, non-nested dictionary to fill a PDF form. As a result of this process, the filled
PDF form will be flattened and no longer editable. This is to prevent future encoding issues, especially when
multiple PDF forms with overlaps on widget names are combined together.
multiple PDF forms with overlaps on widget names are combined.

## Fill text field and checkbox widgets

Expand Down
8 changes: 8 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ It also supports other common utilities such as extracting pages and merging mul
* [Change checkbox and radio button styles](button_style.md)
* [Draw stuffs](draw.md)
* [Other utilities](utils.md)

## Developer Guide

* [Developer Intro](dev_intro.md)
* [Pull Request Requirements](dev_changes.md)
* [Hosting Docs Locally](dev_doc.md)
* [Testing](dev_test.md)
* [Releasing](dev_release.md)
6 changes: 6 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ nav:
- button_style.md
- draw.md
- utils.md
- 'Developer Guide':
- dev_intro.md
- dev_changes.md
- dev_doc.md
- dev_test.md
- dev_release.md
theme:
name: readthedocs
logo: img/logo.png
Expand Down

0 comments on commit dc4a062

Please sign in to comment.