Skip to content

Commit

Permalink
Merge branch 'main' into change/deprecate-legacy-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarrmondragon authored Jul 20, 2023
2 parents 387ae8c + 384cff7 commit 6e435d5
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 75 deletions.
94 changes: 47 additions & 47 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
pytest11 = { callable = "singer_sdk:testing.pytest_plugin", extras = ["testing"] }
pytest11 = { reference = "singer_sdk:testing.pytest_plugin", extras = ["testing"], type = "console" }

[tool.ruff]
exclude = [
Expand Down
7 changes: 5 additions & 2 deletions singer_sdk/sinks/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ def datetime_error_treatment(self) -> DatetimeErrorTreatmentEnum:
def key_properties(self) -> list[str]:
"""Return key properties.
Override this method to return a list of key properties in a format that is
compatible with the target.
Returns:
A list of stream key properties.
"""
Expand Down Expand Up @@ -331,10 +334,10 @@ def _singer_validate_message(self, record: dict) -> None:
Raises:
MissingKeyPropertiesError: If record is missing one or more key properties.
"""
if not all(key_property in record for key_property in self.key_properties):
if any(key_property not in record for key_property in self._key_properties):
msg = (
f"Record is missing one or more key_properties. \n"
f"Key Properties: {self.key_properties}, "
f"Key Properties: {self._key_properties}, "
f"Record Keys: {list(record.keys())}"
)
raise MissingKeyPropertiesError(
Expand Down
28 changes: 4 additions & 24 deletions singer_sdk/tap_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,37 +612,17 @@ class SQLTap(Tap):
# Stream class used to initialize new SQL streams from their catalog declarations.
default_stream_class: type[SQLStream]

def __init__(
self,
*,
config: dict | PurePath | str | list[PurePath | str] | None = None,
catalog: PurePath | str | dict | None = None,
state: PurePath | str | dict | None = None,
parse_env_config: bool = False,
validate_config: bool = True,
) -> None:
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
"""Initialize the SQL tap.
The SQLTap initializer additionally creates a cache variable for _catalog_dict.
Args:
config: Tap configuration. Can be a dictionary, a single path to a
configuration file, or a list of paths to multiple configuration
files.
catalog: Tap catalog. Can be a dictionary or a path to the catalog file.
state: Tap state. Can be dictionary or a path to the state file.
parse_env_config: Whether to look for configuration values in environment
variables.
validate_config: True to require validation of config settings.
*args: Positional arguments for the Tap initializer.
**kwargs: Keyword arguments for the Tap initializer.
"""
self._catalog_dict: dict | None = None
super().__init__(
config=config,
catalog=catalog,
state=state,
parse_env_config=parse_env_config,
validate_config=validate_config,
)
super().__init__(*args, **kwargs)

@property
def catalog_dict(self) -> dict:
Expand Down
4 changes: 4 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ def process_batch(self, context: dict) -> None:
self.target.records_written.extend(context["records"])
self.target.num_batches_processed += 1

@property
def key_properties(self) -> list[str]:
return [key.upper() for key in super().key_properties]


class TargetMock(Target):
"""A mock Target class."""
Expand Down
25 changes: 25 additions & 0 deletions tests/core/test_target_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import copy

import pytest

from singer_sdk.exceptions import MissingKeyPropertiesError
from tests.conftest import BatchSinkMock, TargetMock


Expand All @@ -28,3 +31,25 @@ def test_get_sink():
key_properties=key_properties,
)
assert sink_returned == sink


def test_validate_record():
target = TargetMock()
sink = BatchSinkMock(
target=target,
stream_name="test",
schema={
"properties": {
"id": {"type": ["integer"]},
"name": {"type": ["string"]},
},
},
key_properties=["id"],
)

# Test valid record
sink._singer_validate_message({"id": 1, "name": "test"})

# Test invalid record
with pytest.raises(MissingKeyPropertiesError):
sink._singer_validate_message({"name": "test"})
2 changes: 1 addition & 1 deletion tests/samples/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def path_to_sample_data_db(tmp_path: Path) -> Path:


@pytest.fixture
def sqlite_sample_db_config(path_to_sample_data_db: str) -> dict:
def sqlite_sample_db_config(path_to_sample_data_db: Path) -> dict:
"""Get configuration dictionary for target-csv."""
return {"path_to_db": str(path_to_sample_data_db)}

Expand Down
21 changes: 21 additions & 0 deletions tests/samples/test_tap_sqlite.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from __future__ import annotations

import json
import typing as t

from click.testing import CliRunner

from samples.sample_tap_sqlite import SQLiteTap
from samples.sample_target_csv.csv_target import SampleTargetCSV
from singer_sdk import SQLStream
from singer_sdk._singerlib import MetadataMapping, StreamMetadata
Expand All @@ -24,6 +28,23 @@ def _discover_and_select_all(tap: SQLTap) -> None:
catalog_entry["metadata"] = md.to_list()


def test_tap_sqlite_cli(sqlite_sample_db_config: dict[str, t.Any], tmp_path: Path):
runner = CliRunner()
filepath = tmp_path / "config.json"

with filepath.open("w") as f:
json.dump(sqlite_sample_db_config, f)

result = runner.invoke(
SQLiteTap.cli,
["--discover", "--config", str(filepath)],
)
assert result.exit_code == 0

catalog = json.loads(result.stdout)
assert "streams" in catalog


def test_sql_metadata(sqlite_sample_tap: SQLTap):
stream = t.cast(SQLStream, sqlite_sample_tap.streams["main-t1"])
detected_metadata = stream.catalog_entry["metadata"]
Expand Down

0 comments on commit 6e435d5

Please sign in to comment.