etlplus 0.10.4__tar.gz → 0.10.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {etlplus-0.10.4/etlplus.egg-info → etlplus-0.10.5}/PKG-INFO +1 -1
- {etlplus-0.10.4 → etlplus-0.10.5/etlplus.egg-info}/PKG-INFO +1 -1
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/SOURCES.txt +1 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/conftest.py +105 -4
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/test_u_cli_handlers.py +90 -370
- etlplus-0.10.5/tests/unit/cli/test_u_cli_io.py +326 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/test_u_cli_main.py +59 -25
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/test_u_cli_state.py +45 -41
- {etlplus-0.10.4 → etlplus-0.10.5}/.coveragerc +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.editorconfig +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.gitattributes +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.github/actions/python-bootstrap/action.yml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.github/workflows/ci.yml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.gitignore +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.pre-commit-config.yaml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/.ruff.toml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/CODE_OF_CONDUCT.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/CONTRIBUTING.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/DEMO.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/LICENSE +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/MANIFEST.in +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/Makefile +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/README.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/REFERENCES.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/docs/README.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/docs/pipeline-guide.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/docs/snippets/installation_version.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/__main__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/__version__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/README.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/auth.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/config.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/endpoint_client.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/errors.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/client.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/config.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/paginator.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/rate_limiting/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/rate_limiting/config.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/rate_limiting/rate_limiter.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/request_manager.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/retry_manager.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/transport.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/types.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/commands.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/constants.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/handlers.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/io.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/main.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/options.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/state.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/types.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/connector.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/jobs.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/pipeline.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/profile.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/types.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/utils.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/ddl.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/engine.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/orm.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/schema.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/types.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/enums.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/extract.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/file.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/load.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/mixins.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/py.typed +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/run.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/run_helpers.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/templates/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/templates/ddl.sql.j2 +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/templates/view.sql.j2 +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/transform.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/types.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/utils.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/validate.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/validation/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/validation/utils.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/dependency_links.txt +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/entry_points.txt +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/requires.txt +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/top_level.txt +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/README.md +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/configs/ddl_spec.yml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/configs/pipeline.yml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.csv +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.json +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.xml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.xsd +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.yaml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/examples/quickstart_python.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/pyproject.toml +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/pytest.ini +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/setup.cfg +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/setup.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/__init__.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/conftest.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/conftest.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_cli.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_examples_data_parity.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_pagination_strategy.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_pipeline_smoke.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_pipeline_yaml_load.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_run.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_run_profile_pagination_defaults.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_run_profile_rate_limit_defaults.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/conftest.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_auth.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_config.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_endpoint_client.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_mocks.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_pagination_client.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_pagination_config.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_paginator.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_rate_limit_config.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_rate_limiter.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_request_manager.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_retry_manager.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_transport.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_types.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_config_utils.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_connector.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_jobs.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_pipeline.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/conftest.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_ddl.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_engine.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_orm.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_schema.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_enums.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_extract.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_file.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_load.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_main.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_mixins.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_run.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_run_helpers.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_transform.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_utils.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_validate.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_version.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/validation/test_u_validation_utils.py +0 -0
- {etlplus-0.10.4 → etlplus-0.10.5}/tools/update_demo_snippets.py +0 -0
|
@@ -134,6 +134,7 @@ tests/unit/api/test_u_transport.py
|
|
|
134
134
|
tests/unit/api/test_u_types.py
|
|
135
135
|
tests/unit/cli/conftest.py
|
|
136
136
|
tests/unit/cli/test_u_cli_handlers.py
|
|
137
|
+
tests/unit/cli/test_u_cli_io.py
|
|
137
138
|
tests/unit/cli/test_u_cli_main.py
|
|
138
139
|
tests/unit/cli/test_u_cli_state.py
|
|
139
140
|
tests/unit/config/test_u_config_utils.py
|
|
@@ -14,6 +14,7 @@ from __future__ import annotations
|
|
|
14
14
|
import json
|
|
15
15
|
import types
|
|
16
16
|
from collections.abc import Callable
|
|
17
|
+
from collections.abc import Mapping
|
|
17
18
|
from dataclasses import dataclass
|
|
18
19
|
from dataclasses import field
|
|
19
20
|
from pathlib import Path
|
|
@@ -33,6 +34,84 @@ from etlplus.config import PipelineConfig
|
|
|
33
34
|
|
|
34
35
|
CSV_TEXT: Final[str] = 'a,b\n1,2\n3,4\n'
|
|
35
36
|
|
|
37
|
+
type CaptureHandler = Callable[[object, str], dict[str, object]]
|
|
38
|
+
type CaptureIo = dict[str, list[tuple[tuple[object, ...], dict[str, object]]]]
|
|
39
|
+
type InvokeCli = Callable[..., Result]
|
|
40
|
+
type StubCommand = Callable[[Callable[..., object]], None]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def assert_emit_json(
|
|
44
|
+
calls: CaptureIo,
|
|
45
|
+
payload: object,
|
|
46
|
+
*,
|
|
47
|
+
pretty: bool,
|
|
48
|
+
) -> None:
|
|
49
|
+
"""
|
|
50
|
+
Assert that :func:`emit_json` was called once with expected payload.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
calls : CaptureIo
|
|
55
|
+
Captured IO calls from the CLI fixtures.
|
|
56
|
+
payload : object
|
|
57
|
+
Expected JSON payload.
|
|
58
|
+
pretty : bool
|
|
59
|
+
Expected pretty-print flag.
|
|
60
|
+
"""
|
|
61
|
+
assert calls['emit_json'] == [((payload,), {'pretty': pretty})]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def assert_emit_or_write(
|
|
65
|
+
calls: CaptureIo,
|
|
66
|
+
payload: object,
|
|
67
|
+
target: object,
|
|
68
|
+
*,
|
|
69
|
+
pretty: bool,
|
|
70
|
+
) -> dict[str, object]:
|
|
71
|
+
"""
|
|
72
|
+
Assert that :func:`emit_or_write` was called once and return kwargs.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
calls : CaptureIo
|
|
77
|
+
Captured IO calls from the CLI fixtures.
|
|
78
|
+
payload : object
|
|
79
|
+
Expected payload argument.
|
|
80
|
+
target : object
|
|
81
|
+
Expected output path argument.
|
|
82
|
+
pretty : bool
|
|
83
|
+
Expected pretty-print flag.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
dict[str, object]
|
|
88
|
+
Captured keyword arguments for the call.
|
|
89
|
+
"""
|
|
90
|
+
assert len(calls['emit_or_write']) == 1
|
|
91
|
+
args, kwargs = calls['emit_or_write'][0]
|
|
92
|
+
assert args[0] == payload
|
|
93
|
+
assert args[1] == target
|
|
94
|
+
assert kwargs['pretty'] is pretty
|
|
95
|
+
return kwargs
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def assert_mapping_contains(
|
|
99
|
+
actual: Mapping[str, object],
|
|
100
|
+
expected: Mapping[str, object],
|
|
101
|
+
) -> None:
|
|
102
|
+
"""
|
|
103
|
+
Assert that ``actual`` contains the ``expected`` key/value pairs.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
actual : Mapping[str, object]
|
|
108
|
+
Mapping returned by the handler capture fixture.
|
|
109
|
+
expected : Mapping[str, object]
|
|
110
|
+
Expected key/value pairs that must be present in ``actual``.
|
|
111
|
+
"""
|
|
112
|
+
for key, value in expected.items():
|
|
113
|
+
assert actual[key] == value
|
|
114
|
+
|
|
36
115
|
|
|
37
116
|
@dataclass(frozen=True, slots=True)
|
|
38
117
|
class DummyCfg:
|
|
@@ -60,8 +139,20 @@ class DummyCfg:
|
|
|
60
139
|
@pytest.fixture(name='capture_handler')
|
|
61
140
|
def capture_handler_fixture(
|
|
62
141
|
monkeypatch: pytest.MonkeyPatch,
|
|
63
|
-
) ->
|
|
64
|
-
"""
|
|
142
|
+
) -> CaptureHandler:
|
|
143
|
+
"""
|
|
144
|
+
Patch a handler function and capture the kwargs it receives.
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
----------
|
|
148
|
+
monkeypatch : pytest.MonkeyPatch
|
|
149
|
+
Pytest monkeypatch fixture.
|
|
150
|
+
|
|
151
|
+
Returns
|
|
152
|
+
-------
|
|
153
|
+
CaptureHandler
|
|
154
|
+
Callable that records handler keyword arguments.
|
|
155
|
+
"""
|
|
65
156
|
|
|
66
157
|
def _capture(module: object, attr: str) -> dict[str, object]:
|
|
67
158
|
calls: dict[str, object] = {}
|
|
@@ -77,14 +168,24 @@ def capture_handler_fixture(
|
|
|
77
168
|
|
|
78
169
|
|
|
79
170
|
@pytest.fixture(name='capture_io')
|
|
80
|
-
def capture_io_fixture(monkeypatch: pytest.MonkeyPatch):
|
|
171
|
+
def capture_io_fixture(monkeypatch: pytest.MonkeyPatch) -> CaptureIo:
|
|
81
172
|
"""
|
|
82
173
|
Patch handler functions and capture CLI output.
|
|
83
174
|
Returns a dict with lists of call args for each function.
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
monkeypatch : pytest.MonkeyPatch
|
|
179
|
+
Pytest monkeypatch fixture.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
CaptureIo
|
|
184
|
+
Mapping of captured IO call arguments by function name.
|
|
84
185
|
"""
|
|
85
186
|
import etlplus.cli.io as _io
|
|
86
187
|
|
|
87
|
-
calls:
|
|
188
|
+
calls: CaptureIo = {
|
|
88
189
|
'emit_or_write': [],
|
|
89
190
|
'emit_json': [],
|
|
90
191
|
'print_json': [],
|