diff --git a/pyproject.toml b/pyproject.toml index c4478d3..63a0ad8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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 ", diff --git a/src/pytest_mock_resources/__init__.py b/src/pytest_mock_resources/__init__.py index c3511e1..c5cf5a2 100644 --- a/src/pytest_mock_resources/__init__.py +++ b/src/pytest_mock_resources/__init__.py @@ -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, @@ -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", diff --git a/src/pytest_mock_resources/fixture/__init__.py b/src/pytest_mock_resources/fixture/__init__.py index adfcee8..5b8da92 100644 --- a/src/pytest_mock_resources/fixture/__init__.py +++ b/src/pytest_mock_resources/fixture/__init__.py @@ -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, @@ -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", diff --git a/src/pytest_mock_resources/fixture/postgresql.py b/src/pytest_mock_resources/fixture/postgresql.py index cf3af5e..0d13e52 100644 --- a/src/pytest_mock_resources/fixture/postgresql.py +++ b/src/pytest_mock_resources/fixture/postgresql.py @@ -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__) @@ -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, @@ -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() diff --git a/src/pytest_mock_resources/fixture/redis.py b/src/pytest_mock_resources/fixture/redis.py index e6a1584..a0981d5 100644 --- a/src/pytest_mock_resources/fixture/redis.py +++ b/src/pytest_mock_resources/fixture/redis.py @@ -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