-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #655 from chinapandaman/PPF-615
PPF-615: create developer guide docs
- Loading branch information
Showing
8 changed files
with
204 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters