Repository: meltano/sdk
Pull request #1775 (2023-06-19 19:47:03)

fix: Add tests for SQL type conversion from JSON schemas
Closes https://github.com/meltano/sdk/issues/1774

I added tests that I let run in CI and they fail https://github.com/meltano/sdk/actions/runs/5315601259/jobs/9624162264 then I pushed the change that fixes them.

<!-- readthedocs-preview meltano-sdk start -->
----
:books: Documentation preview :books:: https://meltano-sdk--1775.org.readthedocs.build/en/1775/

<!-- readthedocs-preview meltano-sdk end -->

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/meltano/sdk/pull/1775?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) Report
> Merging [#1775](https://app.codecov.io/gh/meltano/sdk/pull/1775?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) (9b13a09) into [main](https://app.codecov.io/gh/meltano/sdk/commit/e8772158aa7b4a0f87fb280d40bba68f8c0e72e3?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) (e877215) will **increase** coverage by `0.08%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##             main    #1775      +/-   ##
==========================================
+ Coverage   85.61%   85.69%   +0.08%     
==========================================
  Files          59       59              
  Lines        4937     4937              
  Branches      809      809              
==========================================
+ Hits         4227     4231       +4     
+ Misses        507      505       -2     
+ Partials      203      201       -2     
```


| [Impacted Files](https://app.codecov.io/gh/meltano/sdk/pull/1775?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) | Coverage Δ | |
|---|---|---|
| [singer\_sdk/typing.py](https://app.codecov.io/gh/meltano/sdk/pull/1775?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano#diff-c2luZ2VyX3Nkay90eXBpbmcucHk=) | `96.77% <100.00%> (+1.84%)` | :arrow_up: |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano)

edgarrmondragon: This is great, thanks @pnadolny13!

Patch:
diff --git a/singer_sdk/typing.py b/singer_sdk/typing.py
index f2766944..1e70f620 100644
--- a/singer_sdk/typing.py
+++ b/singer_sdk/typing.py
@@ -825,7 +825,9 @@ def _jsonschema_type_check(jsonschema_type: dict, type_check: tuple[str]) -> boo
             if jsonschema_type.get("type") in type_check:  # noqa: PLR5501
                 return True
 
-    if any(t in type_check for t in jsonschema_type.get("anyOf", ())):
+    if any(
+        _jsonschema_type_check(t, type_check) for t in jsonschema_type.get("anyOf", ())
+    ):
         return True
 
     return False


Test patch:
diff --git a/tests/core/test_typing.py b/tests/core/test_typing.py
index 854669e5..b2cf9c69 100644
--- a/tests/core/test_typing.py
+++ b/tests/core/test_typing.py
@@ -4,7 +4,9 @@ from __future__ import annotations
 
 import datetime
 import logging
-import typing as t
+
+import pytest
+import sqlalchemy
 
 from singer_sdk.helpers._typing import (
     TypeConformanceLevel,
@@ -17,11 +19,9 @@ from singer_sdk.typing import (
     PropertiesList,
     Property,
     StringType,
+    to_sql_type,
 )
 
-if t.TYPE_CHECKING:
-    import pytest
-
 logger = logging.getLogger("log")
 
 
@@ -292,3 +292,29 @@ def test_conform_primitives():
     assert _conform_primitive_property(None, {"type": "boolean"}) is None
     assert _conform_primitive_property(0, {"type": "boolean"}) is False
     assert _conform_primitive_property(1, {"type": "boolean"}) is True
+
+
+@pytest.mark.parametrize(
+    "jsonschema_type,expected",
+    [
+        ({"type": ["string", "null"]}, sqlalchemy.types.VARCHAR),
+        ({"type": ["integer", "null"]}, sqlalchemy.types.INTEGER),
+        ({"type": ["number", "null"]}, sqlalchemy.types.DECIMAL),
+        ({"type": ["boolean", "null"]}, sqlalchemy.types.BOOLEAN),
+        ({"type": "object", "properties": {}}, sqlalchemy.types.VARCHAR),
+        ({"type": "array"}, sqlalchemy.types.VARCHAR),
+        ({"format": "date", "type": ["string", "null"]}, sqlalchemy.types.DATE),
+        ({"format": "time", "type": ["string", "null"]}, sqlalchemy.types.TIME),
+        (
+            {"format": "date-time", "type": ["string", "null"]},
+            sqlalchemy.types.DATETIME,
+        ),
+        (
+            {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}]},
+            sqlalchemy.types.DATETIME,
+        ),
+        ({"anyOf": [{"type": "integer"}, {"type": "null"}]}, sqlalchemy.types.INTEGER),
+    ],
+)
+def test_to_sql_type(jsonschema_type, expected):
+    assert isinstance(to_sql_type(jsonschema_type), expected)