diff --git a/pyproject.toml b/pyproject.toml index ac44995..dcff51d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "jcloud-docsgen" version = "0.1.0" description = "A project documentation generator" -dependencies = ["docstring-parser"] +dependencies = ["docstring-parser", "pytest-dir-equal"] license = "Apache-2.0" [project.scripts] diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator.py index 75a6ffc..88b17f6 100644 --- a/tests/unit/core/python/_core/test_PythonDocumentationGenerator.py +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator.py @@ -14,8 +14,9 @@ from src.jcloud_docsgen.core.python import PythonDocumentationGenerator from src.jcloud_docsgen.core.python.namespaces import PythonModuleNamespace, PythonPackageNamespace -import pytest from src.jcloud_docsgen.utils import ExistingDirectory +import pytest +import pathlib @pytest.mark.parametrize('project_directory,docs_directory,expected_exception,expected_exception_msg', [ (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')])])]), ]) def test_PythonDocumentationGenerator_collect_modules(python_documentation_generator: PythonDocumentationGenerator, expected): - assert python_documentation_generator.namespace() == expected \ No newline at end of file + 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 \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case01/expected/.gitkeep b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case01/expected/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case01/initial/.gitkeep b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case01/initial/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case01/project/src/.gitkeep b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case01/project/src/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case02/expected/pkg/module.md b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case02/expected/pkg/module.md new file mode 100644 index 0000000..c95a23a --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case02/expected/pkg/module.md @@ -0,0 +1,9 @@ +# Module `pkg.module` + +## Function `func` + +### Function signature + +```python +func() +``` \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case02/project/src/pkg/module.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case02/project/src/pkg/module.py new file mode 100644 index 0000000..6d54bce --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case02/project/src/pkg/module.py @@ -0,0 +1 @@ +def func(): ... \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/exceptions.md b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/exceptions.md new file mode 100644 index 0000000..92eaa35 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/exceptions.md @@ -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. \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/models.md b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/models.md new file mode 100644 index 0000000..5b9f54b --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/models.md @@ -0,0 +1,21 @@ +# Module `user_management.models` + +## Class `User` + +Represents a user. + + + + + +### Decorators + +```python +dataclass +``` + + + +### Docstring + +Represents a user. \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/service.md b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/service.md new file mode 100644 index 0000000..1af12f0 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/service.md @@ -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. \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/storage.md b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/storage.md new file mode 100644 index 0000000..8753e51 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/storage.md @@ -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. \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/utils.md b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/utils.md new file mode 100644 index 0000000..e300902 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/expected/user_management/utils.md @@ -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. \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/exceptions.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/exceptions.py new file mode 100644 index 0000000..6d29928 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/exceptions.py @@ -0,0 +1,8 @@ +class UserNotFoundError(Exception): + """User does not exist.""" + pass + + +class InvalidEmailError(Exception): + """Email address is invalid.""" + pass \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/models.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/models.py new file mode 100644 index 0000000..1f7cc5f --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/models.py @@ -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 \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/service.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/service.py new file mode 100644 index 0000000..67c2f61 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/service.py @@ -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) \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/storage.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/storage.py new file mode 100644 index 0000000..29ff61d --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/storage.py @@ -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()) \ No newline at end of file diff --git a/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/utils.py b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/utils.py new file mode 100644 index 0000000..5ca8309 --- /dev/null +++ b/tests/unit/core/python/_core/test_PythonDocumentationGenerator/test_generate_documentation/case03/project/src/user_management/utils.py @@ -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() \ No newline at end of file