|
6 | 6 | import json |
7 | 7 | import logging |
8 | 8 | import sys |
| 9 | +import tempfile |
9 | 10 | import types |
10 | 11 | from collections.abc import Callable, Mapping |
11 | 12 | from pathlib import Path |
|
17 | 18 | from airbyte_protocol_dataclasses.models.airbyte_protocol import AirbyteCatalog |
18 | 19 |
|
19 | 20 | from airbyte_cdk.cli.source_declarative_manifest._run import ( |
| 21 | + _parse_components_from_args, |
| 22 | + _register_components_from_file, |
20 | 23 | create_declarative_source, |
21 | 24 | ) |
22 | 25 | from airbyte_cdk.models import ConfiguredAirbyteCatalog, ConfiguredAirbyteStream |
@@ -288,3 +291,89 @@ def _read_fn(*args, **kwargs): |
288 | 291 | _read_fn() |
289 | 292 | else: |
290 | 293 | _read_fn() |
| 294 | + |
| 295 | + |
| 296 | +def test_register_components_from_file() -> None: |
| 297 | + """Test that components can be properly loaded from a file.""" |
| 298 | + # Create a temporary file with the sample components |
| 299 | + with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as temp_file: |
| 300 | + temp_file.write(SAMPLE_COMPONENTS_PY_TEXT) |
| 301 | + temp_file.flush() |
| 302 | + file_path = temp_file.name |
| 303 | + |
| 304 | + try: |
| 305 | + # Register the components |
| 306 | + _register_components_from_file(file_path) |
| 307 | + |
| 308 | + # Verify the components were loaded correctly |
| 309 | + import components |
| 310 | + |
| 311 | + assert hasattr(components, "sample_function") |
| 312 | + assert components.sample_function() == "Hello, World!" |
| 313 | + |
| 314 | + # Verify the components module is registered in sys.modules |
| 315 | + assert "components" in sys.modules |
| 316 | + assert "source_declarative_manifest.components" in sys.modules |
| 317 | + |
| 318 | + # Verify they are the same module |
| 319 | + assert sys.modules["components"] is sys.modules["source_declarative_manifest.components"] |
| 320 | + |
| 321 | + # Clean up the modules |
| 322 | + if "components" in sys.modules: |
| 323 | + del sys.modules["components"] |
| 324 | + if "source_declarative_manifest.components" in sys.modules: |
| 325 | + del sys.modules["source_declarative_manifest.components"] |
| 326 | + finally: |
| 327 | + # Clean up the temporary file |
| 328 | + Path(file_path).unlink(missing_ok=True) |
| 329 | + |
| 330 | + |
| 331 | +def test_parse_components_from_args(monkeypatch: pytest.MonkeyPatch) -> None: |
| 332 | + """Test that components can be loaded from command line arguments.""" |
| 333 | + # Create a temporary file with sample components |
| 334 | + with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as temp_file: |
| 335 | + temp_file.write(SAMPLE_COMPONENTS_PY_TEXT) |
| 336 | + temp_file.flush() |
| 337 | + file_path = temp_file.name |
| 338 | + |
| 339 | + # Mock the arguments |
| 340 | + class MockArgs: |
| 341 | + components_path = file_path |
| 342 | + |
| 343 | + # Mock the parse_args function to return our mock args |
| 344 | + def mock_parse_args(*args: Any, **kwargs: Any) -> Any: |
| 345 | + return MockArgs() |
| 346 | + |
| 347 | + # Apply the monkeypatch |
| 348 | + from airbyte_cdk.entrypoint import AirbyteEntrypoint |
| 349 | + |
| 350 | + monkeypatch.setattr(AirbyteEntrypoint, "parse_args", mock_parse_args) |
| 351 | + |
| 352 | + try: |
| 353 | + # Call the function with any args (they'll be ignored due to the mock) |
| 354 | + result = _parse_components_from_args(["some", "args"]) |
| 355 | + |
| 356 | + # Verify result |
| 357 | + assert result is True # Should return True when successful |
| 358 | + |
| 359 | + # Verify the components were loaded |
| 360 | + import components |
| 361 | + |
| 362 | + assert hasattr(components, "sample_function") |
| 363 | + assert components.sample_function() == "Hello, World!" |
| 364 | + |
| 365 | + # Verify both module names are registered |
| 366 | + assert "components" in sys.modules |
| 367 | + assert "source_declarative_manifest.components" in sys.modules |
| 368 | + |
| 369 | + # Verify they are the same module |
| 370 | + assert sys.modules["components"] is sys.modules["source_declarative_manifest.components"] |
| 371 | + |
| 372 | + # Clean up the modules |
| 373 | + if "components" in sys.modules: |
| 374 | + del sys.modules["components"] |
| 375 | + if "source_declarative_manifest.components" in sys.modules: |
| 376 | + del sys.modules["source_declarative_manifest.components"] |
| 377 | + finally: |
| 378 | + # Clean up the temporary file |
| 379 | + Path(file_path).unlink(missing_ok=True) |
0 commit comments