From faa7befd9b73f543694bafc7430e0426eba882e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= Date: Wed, 16 Aug 2023 16:48:33 -0600 Subject: [PATCH 1/3] fix: Fix tap tests for multiple test classes with different input catalogs --- singer_sdk/testing/factory.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/singer_sdk/testing/factory.py b/singer_sdk/testing/factory.py index c7611955f..e5205847e 100644 --- a/singer_sdk/testing/factory.py +++ b/singer_sdk/testing/factory.py @@ -21,8 +21,13 @@ class BaseTestClass: """Base test class.""" - params: t.ClassVar[dict] = {} - param_ids: t.ClassVar[dict] = {} + params: dict[str, t.Any] + param_ids: dict[str, list[str]] + + def __init_subclass__(cls) -> None: + """Initialize a subclass.""" + cls.params = {} + cls.param_ids = {} class TapTestClassFactory: @@ -183,7 +188,7 @@ def _annotate_test_class( # noqa: C901 test = test_class() test_name = f"test_{suite.kind}_{test.name}" test_params = [] - test_ids = [] + test_ids: list[str] = [] for stream in streams: test_params.extend( [ From 99690b0536ca820c9c82fb0c239a2a4d4e72d826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= Date: Wed, 16 Aug 2023 19:51:02 -0600 Subject: [PATCH 2/3] Fix mro mess --- singer_sdk/testing/factory.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/singer_sdk/testing/factory.py b/singer_sdk/testing/factory.py index e5205847e..1c15f4844 100644 --- a/singer_sdk/testing/factory.py +++ b/singer_sdk/testing/factory.py @@ -24,10 +24,17 @@ class BaseTestClass: params: dict[str, t.Any] param_ids: dict[str, list[str]] - def __init_subclass__(cls) -> None: - """Initialize a subclass.""" - cls.params = {} - cls.param_ids = {} + def __init_subclass__(cls, **kwargs: t.Any) -> None: + """Initialize a subclass. + + Args: + **kwargs: Keyword arguments. + """ + # Add empty params and param_ids attributes to a direct subclass but not to + # subclasses of subclasses + if cls.__base__ == BaseTestClass: + cls.params = {} + cls.param_ids = {} class TapTestClassFactory: From 5d8c0be99a195cb9c45647fdfdf1cd73043d93e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= Date: Wed, 16 Aug 2023 20:07:46 -0600 Subject: [PATCH 3/3] Test the test class mro --- tests/core/test_testing.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/core/test_testing.py b/tests/core/test_testing.py index 02672d9ad..5715cd1e1 100644 --- a/tests/core/test_testing.py +++ b/tests/core/test_testing.py @@ -4,6 +4,8 @@ import pytest +from singer_sdk.testing.factory import BaseTestClass + def test_module_deprecations(): with pytest.deprecated_call(): @@ -19,3 +21,23 @@ def test_module_deprecations(): match="module singer_sdk.testing has no attribute", ): testing.foo # noqa: B018 + + +def test_test_class_mro(): + class PluginTestClass(BaseTestClass): + pass + + PluginTestClass.params["x"] = 1 + + class AnotherPluginTestClass(BaseTestClass): + pass + + AnotherPluginTestClass.params["x"] = 2 + AnotherPluginTestClass.params["y"] = 3 + + class SubPluginTestClass(PluginTestClass): + pass + + assert PluginTestClass.params == {"x": 1} + assert AnotherPluginTestClass.params == {"x": 2, "y": 3} + assert SubPluginTestClass.params == {"x": 1}