Skip to content

Commit

Permalink
feat: Expose postgres fixture factory functions for controlling conta…
Browse files Browse the repository at this point in the history
…iner scope.
  • Loading branch information
DanCardin committed Sep 17, 2024
1 parent f1196b3 commit f96ecbc
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pytest-mock-resources"
version = "2.12.0"
version = "2.12.1"
description = "A pytest plugin for easily instantiating reproducible mock resources."
authors = [
"Omar Khan <[email protected]>",
Expand Down
4 changes: 4 additions & 0 deletions src/pytest_mock_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
create_mongo_fixture,
create_moto_fixture,
create_mysql_fixture,
create_postgres_config_fixture,
create_postgres_container_fixture,
create_postgres_fixture,
create_redis_fixture,
create_redshift_fixture,
Expand Down Expand Up @@ -56,6 +58,8 @@
"create_moto_fixture",
"create_mysql_fixture",
"create_postgres_fixture",
"create_postgres_config_fixture",
"create_postgres_container_fixture",
"create_redis_fixture",
"create_redshift_fixture",
"create_sqlite_fixture",
Expand Down
4 changes: 4 additions & 0 deletions src/pytest_mock_resources/fixture/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
pmr_mysql_container,
)
from pytest_mock_resources.fixture.postgresql import (
create_postgres_config_fixture,
create_postgres_container_fixture,
create_postgres_fixture,
pmr_postgres_config,
pmr_postgres_container,
Expand All @@ -39,6 +41,8 @@
"create_moto_fixture",
"create_mysql_fixture",
"create_postgres_fixture",
"create_postgres_config_fixture",
"create_postgres_container_fixture",
"create_redis_fixture",
"create_redshift_fixture",
"create_sqlite_fixture",
Expand Down
80 changes: 68 additions & 12 deletions src/pytest_mock_resources/fixture/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,23 @@
get_sqlalchemy_engine,
PostgresConfig,
)
from pytest_mock_resources.fixture.base import asyncio_fixture, generate_fixture_id
from pytest_mock_resources.fixture.base import asyncio_fixture, generate_fixture_id, Scope
from pytest_mock_resources.sqlalchemy import (
bifurcate_actions,
EngineManager,
normalize_actions,
)

__all__ = [
"DatabaseExistsError",
"PostgresConfig",
"create_postgres_config_fixture",
"create_postgres_container_fixture",
"create_postgres_fixture",
"pmr_postgres_config",
"pmr_postgres_container",
]

log = logging.getLogger(__name__)


Expand All @@ -35,26 +45,68 @@ class DatabaseExistsError(RuntimeError):
"""


@pytest.fixture(scope="session")
def pmr_postgres_config():
"""Override this fixture with a :class:`PostgresConfig` instance to specify different defaults.
def create_postgres_config_fixture(
config: PostgresConfig | None = None, *, scope: Scope = "session"
):
"""Create a fixture for a :class:`PostgresConfig` instance.
Arguments:
config: A postgres configuration instance to use as the default.
scope: The scope of the fixture. Defaults to "session".
>>> pmr_postgres_config = create_postgres_config_fixture(PostgresConfig(), scope="session")
is exactly equivalent to
>>> @pytest.fixture(scope="session")
... def pmr_postgres_config():
... return PostgresConfig()
"""
if config is None:
config = PostgresConfig()

@pytest.fixture(scope=scope)
def fixture():
"""Override this fixture with a :class:`PostgresConfig` instance to specify different defaults.
Examples:
>>> @pytest.fixture(scope='session')
... def pmr_postgres_config():
... return PostgresConfig(image="postgres:9.6.10", root_database="foo")
"""
return config

return fixture


def create_postgres_container_fixture(
*, config: PostgresConfig | None = None, scope: Scope = "session"
):
"""Create a fixture for the underlying postgres container.
This fixture factory is primarily useful as a mechanism to adjust the container's fixture scope,
which would only otherwise be possible by inlining the default fixture's source implementation.
Examples:
>>> @pytest.fixture(scope='session')
... def pmr_postgres_config():
... return PostgresConfig(image="postgres:9.6.10", root_database="foo")
>>> pmr_postgres_container = create_postgres_container_fixture(scope="function")
Arguments:
config: A postgres configuration instance to use as the default. When left unspecified, defaults
to the `pmr_postgres_config` fixture.
scope: The scope of the fixture. Defaults to "session".
"""
return PostgresConfig()

@pytest.fixture(scope=scope)
def fixture(pytestconfig, pmr_postgres_config: PostgresConfig):
postgres_config = config or pmr_postgres_config
yield from get_container(pytestconfig, postgres_config)

@pytest.fixture(scope="session")
def pmr_postgres_container(pytestconfig, pmr_postgres_config: PostgresConfig):
yield from get_container(pytestconfig, pmr_postgres_config)
return fixture


def create_postgres_fixture(
*ordered_actions,
scope="function",
scope: Scope = "function",
tables=None,
session=None,
async_=False,
Expand Down Expand Up @@ -302,3 +354,7 @@ def _generate_database_name(conn):
result = conn.execute(text("INSERT INTO pytest_mock_resource_db VALUES (DEFAULT) RETURNING id"))
id_ = next(iter(result))[0]
return f"pytest_mock_resource_db_{id_}"


pmr_postgres_config = create_postgres_config_fixture()
pmr_postgres_container = create_postgres_container_fixture()
1 change: 1 addition & 0 deletions src/pytest_mock_resources/fixture/redis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from pytest_mock_resources.compat import redis
from pytest_mock_resources.container.base import get_container
from pytest_mock_resources.container.redis import RedisConfig
Expand Down

0 comments on commit f96ecbc

Please sign in to comment.