generated from jCloud/repository-template
Add tests for the Python project documentation generator
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
name = "jcloud-docsgen"
|
name = "jcloud-docsgen"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "A project documentation generator"
|
description = "A project documentation generator"
|
||||||
dependencies = ["docstring-parser"]
|
dependencies = ["docstring-parser", "pytest-dir-equal"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|||||||
@@ -14,8 +14,9 @@
|
|||||||
|
|
||||||
from src.jcloud_docsgen.core.python import PythonDocumentationGenerator
|
from src.jcloud_docsgen.core.python import PythonDocumentationGenerator
|
||||||
from src.jcloud_docsgen.core.python.namespaces import PythonModuleNamespace, PythonPackageNamespace
|
from src.jcloud_docsgen.core.python.namespaces import PythonModuleNamespace, PythonPackageNamespace
|
||||||
import pytest
|
|
||||||
from src.jcloud_docsgen.utils import ExistingDirectory
|
from src.jcloud_docsgen.utils import ExistingDirectory
|
||||||
|
import pytest
|
||||||
|
import pathlib
|
||||||
|
|
||||||
@pytest.mark.parametrize('project_directory,docs_directory,expected_exception,expected_exception_msg', [
|
@pytest.mark.parametrize('project_directory,docs_directory,expected_exception,expected_exception_msg', [
|
||||||
(1, 1, TypeError, 'expected \'ExistingDirectory\', got \'int\''),
|
(1, 1, TypeError, 'expected \'ExistingDirectory\', got \'int\''),
|
||||||
@@ -38,4 +39,24 @@ def test_PythonDocumentationGenerator_exceptions(project_directory, docs_directo
|
|||||||
(PythonDocumentationGenerator(ExistingDirectory('tests/unit/core/python/_core/test_project_dirs/pdir_3'), ExistingDirectory('tests/unit/core/python/_core/test_project_dirs/pdir_3/docs')), [PythonPackageNamespace('pkg', [PythonModuleNamespace('module'), PythonPackageNamespace('pkg', [PythonModuleNamespace('module2')])])]),
|
(PythonDocumentationGenerator(ExistingDirectory('tests/unit/core/python/_core/test_project_dirs/pdir_3'), ExistingDirectory('tests/unit/core/python/_core/test_project_dirs/pdir_3/docs')), [PythonPackageNamespace('pkg', [PythonModuleNamespace('module'), PythonPackageNamespace('pkg', [PythonModuleNamespace('module2')])])]),
|
||||||
])
|
])
|
||||||
def test_PythonDocumentationGenerator_collect_modules(python_documentation_generator: PythonDocumentationGenerator, expected):
|
def test_PythonDocumentationGenerator_collect_modules(python_documentation_generator: PythonDocumentationGenerator, expected):
|
||||||
assert python_documentation_generator.namespace() == expected
|
assert python_documentation_generator.namespace() == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('dir', [
|
||||||
|
d.name
|
||||||
|
for d in pathlib.Path('tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/').iterdir()
|
||||||
|
])
|
||||||
|
def test_generate_documentation(dir, expectdir):
|
||||||
|
with expectdir('test_PythonDocumentationGenerator/test_generate_documentation/' + dir) as d:
|
||||||
|
PythonDocumentationGenerator(
|
||||||
|
ExistingDirectory(
|
||||||
|
str(
|
||||||
|
pathlib.Path('tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/') /
|
||||||
|
dir /
|
||||||
|
'project'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ExistingDirectory(str(d)),
|
||||||
|
allow_tables = True,
|
||||||
|
allow_html = False
|
||||||
|
).generate_documentation(
|
||||||
|
) # simplify the tests
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
# Module `pkg.module`
|
||||||
|
|
||||||
|
## Function `func`
|
||||||
|
|
||||||
|
### Function signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
func()
|
||||||
|
```
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
def func(): ...
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
# Module `user_management.exceptions`
|
||||||
|
|
||||||
|
## Class `UserNotFoundError`
|
||||||
|
|
||||||
|
User does not exist.
|
||||||
|
|
||||||
|
### Base classes
|
||||||
|
|
||||||
|
- `Exception`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
User does not exist.
|
||||||
|
|
||||||
|
## Class `InvalidEmailError`
|
||||||
|
|
||||||
|
Email address is invalid.
|
||||||
|
|
||||||
|
### Base classes
|
||||||
|
|
||||||
|
- `Exception`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
Email address is invalid.
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Module `user_management.models`
|
||||||
|
|
||||||
|
## Class `User`
|
||||||
|
|
||||||
|
Represents a user.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Decorators
|
||||||
|
|
||||||
|
```python
|
||||||
|
dataclass
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
Represents a user.
|
||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
# Module `user_management.service`
|
||||||
|
|
||||||
|
## Class `UserService`
|
||||||
|
|
||||||
|
Central class for the user management.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Body
|
||||||
|
|
||||||
|
#### Constructor (method `__init__`)
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
__init__(self, storage: InMemoryUserStorage)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `storage` | `InMemoryUserStorage` | normal | -- | -- |
|
||||||
|
|
||||||
|
#### Method `create_user`
|
||||||
|
|
||||||
|
Creates and stores a new user.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
create_user(self, user_id: str, name: str, email: str, age: int | None = None) -> User
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `User`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `user_id` | `str` | normal | -- | -- |
|
||||||
|
| `name` | `str` | normal | -- | -- |
|
||||||
|
| `email` | `str` | normal | -- | -- |
|
||||||
|
| `age` | `int | None` | normal | `None` | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Creates and stores a new user.
|
||||||
|
|
||||||
|
#### Method `get_user`
|
||||||
|
|
||||||
|
Returns a user.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
get_user(self, user_id: str) -> User
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `User`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `user_id` | `str` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Returns a user.
|
||||||
|
|
||||||
|
#### Method `delete_user`
|
||||||
|
|
||||||
|
Deletes a user.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
delete_user(self, user_id: str) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `None`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `user_id` | `str` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Deletes a user.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
Central class for the user management.
|
||||||
+158
@@ -0,0 +1,158 @@
|
|||||||
|
# Module `user_management.storage`
|
||||||
|
|
||||||
|
## Class `InMemoryUserStorage`
|
||||||
|
|
||||||
|
A simple in-memory storage for users.
|
||||||
|
Intended for testing purposes only.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Body
|
||||||
|
|
||||||
|
#### Constructor (method `__init__`)
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
__init__(self)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
|
||||||
|
#### Method `add`
|
||||||
|
|
||||||
|
Adds a user.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
add(self, user: User) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `None`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `user` | `User` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Adds a user.
|
||||||
|
|
||||||
|
#### Method `get`
|
||||||
|
|
||||||
|
Returns a user based on their ID.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
get(self, user_id: str) -> User
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `User`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `user_id` | `str` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Returns a user based on their ID.
|
||||||
|
|
||||||
|
#### Method `delete`
|
||||||
|
|
||||||
|
Deletes a user.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
delete(self, user_id: str) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `None`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
| `user_id` | `str` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Deletes a user.
|
||||||
|
|
||||||
|
#### Method `list_all`
|
||||||
|
|
||||||
|
Returns all users.
|
||||||
|
|
||||||
|
##### Method signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
list_all(self) -> List[User]
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Returns
|
||||||
|
|
||||||
|
Return type: `List[User]`
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `self` | -- | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Docstring
|
||||||
|
|
||||||
|
Returns all users.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
A simple in-memory storage for users.
|
||||||
|
Intended for testing purposes only.
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
# Module `user_management.utils`
|
||||||
|
|
||||||
|
## Function `is_valid_email`
|
||||||
|
|
||||||
|
Checks whether an email address is valid.
|
||||||
|
|
||||||
|
### Function signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
is_valid_email(email: str) -> bool
|
||||||
|
```
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
Return type: `bool`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `email` | `str` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
Checks whether an email address is valid.
|
||||||
|
|
||||||
|
## Function `normalize_name`
|
||||||
|
|
||||||
|
Removes extra spaces and formats the name.
|
||||||
|
|
||||||
|
### Function signature
|
||||||
|
|
||||||
|
```python
|
||||||
|
normalize_name(name: str) -> str
|
||||||
|
```
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
|
||||||
|
Return type: `str`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Kind | Default value | Description |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `name` | `str` | normal | -- | -- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Docstring
|
||||||
|
|
||||||
|
Removes extra spaces and formats the name.
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class UserNotFoundError(Exception):
|
||||||
|
"""User does not exist."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidEmailError(Exception):
|
||||||
|
"""Email address is invalid."""
|
||||||
|
pass
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class User:
|
||||||
|
"""
|
||||||
|
Represents a user.
|
||||||
|
"""
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
email: str
|
||||||
|
age: Optional[int] = None
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
from .models import User
|
||||||
|
from .storage import InMemoryUserStorage
|
||||||
|
from .exceptions import UserNotFoundError, InvalidEmailError
|
||||||
|
from .utils import is_valid_email, normalize_name
|
||||||
|
|
||||||
|
|
||||||
|
class UserService:
|
||||||
|
"""
|
||||||
|
Central class for the user management.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, storage: InMemoryUserStorage):
|
||||||
|
self.storage = storage
|
||||||
|
|
||||||
|
def create_user(self, user_id: str, name: str, email: str, age: int | None = None) -> User:
|
||||||
|
"""
|
||||||
|
Creates and stores a new user.
|
||||||
|
"""
|
||||||
|
if not is_valid_email(email):
|
||||||
|
raise InvalidEmailError(f"Invalid email: {email}")
|
||||||
|
|
||||||
|
user = User(
|
||||||
|
id=user_id,
|
||||||
|
name=normalize_name(name),
|
||||||
|
email=email,
|
||||||
|
age=age
|
||||||
|
)
|
||||||
|
|
||||||
|
self.storage.add(user)
|
||||||
|
return user
|
||||||
|
|
||||||
|
def get_user(self, user_id: str) -> User:
|
||||||
|
"""
|
||||||
|
Returns a user.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self.storage.get(user_id)
|
||||||
|
except KeyError:
|
||||||
|
raise UserNotFoundError(user_id)
|
||||||
|
|
||||||
|
def delete_user(self, user_id: str) -> None:
|
||||||
|
"""
|
||||||
|
Deletes a user.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self.storage.delete(user_id)
|
||||||
|
except KeyError:
|
||||||
|
raise UserNotFoundError(user_id)
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
from typing import Dict, List
|
||||||
|
from .models import User
|
||||||
|
|
||||||
|
|
||||||
|
class InMemoryUserStorage:
|
||||||
|
"""
|
||||||
|
A simple in-memory storage for users.
|
||||||
|
Intended for testing purposes only.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._users: Dict[str, User] = {}
|
||||||
|
|
||||||
|
def add(self, user: User) -> None:
|
||||||
|
"""Adds a user."""
|
||||||
|
self._users[user.id] = user
|
||||||
|
|
||||||
|
def get(self, user_id: str) -> User:
|
||||||
|
"""Returns a user based on their ID."""
|
||||||
|
return self._users[user_id]
|
||||||
|
|
||||||
|
def delete(self, user_id: str) -> None:
|
||||||
|
"""Deletes a user."""
|
||||||
|
del self._users[user_id]
|
||||||
|
|
||||||
|
def list_all(self) -> List[User]:
|
||||||
|
"""Returns all users."""
|
||||||
|
return list(self._users.values())
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_email(email: str) -> bool:
|
||||||
|
"""
|
||||||
|
Checks whether an email address is valid.
|
||||||
|
"""
|
||||||
|
pattern = r"^[\w\.-]+@[\w\.-]+\.\w+$"
|
||||||
|
return re.match(pattern, email) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_name(name: str) -> str:
|
||||||
|
"""
|
||||||
|
Removes extra spaces and formats the name.
|
||||||
|
"""
|
||||||
|
return " ".join(name.strip().split()).title()
|
||||||
Reference in New Issue
Block a user