|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import os |
| 4 | +import tempfile |
3 | 5 | from collections.abc import Generator
|
4 | 6 | from pathlib import Path
|
5 | 7 | from typing import TYPE_CHECKING
|
@@ -170,3 +172,132 @@ def test_cli_group_creation() -> None:
|
170 | 172 | assert "drop-all" in cli_group.commands
|
171 | 173 | assert "dump-data" in cli_group.commands
|
172 | 174 | assert "stamp" in cli_group.commands
|
| 175 | + |
| 176 | + |
| 177 | +def test_external_config_loading(cli_runner: CliRunner) -> None: |
| 178 | + """Test loading config from external module in current working directory.""" |
| 179 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 180 | + temp_path = Path(temp_dir) |
| 181 | + |
| 182 | + # Create an external config file in the temp directory |
| 183 | + config_file = temp_path / "external_config.py" |
| 184 | + config_file.write_text(""" |
| 185 | +from advanced_alchemy.config import SQLAlchemyAsyncConfig |
| 186 | +
|
| 187 | +config = SQLAlchemyAsyncConfig( |
| 188 | + connection_string="sqlite+aiosqlite:///:memory:", |
| 189 | + bind_key="external", |
| 190 | +) |
| 191 | +""") |
| 192 | + |
| 193 | + # Change to the temp directory |
| 194 | + original_cwd = os.getcwd() |
| 195 | + try: |
| 196 | + os.chdir(temp_dir) |
| 197 | + |
| 198 | + # Test that the external config can be loaded |
| 199 | + cli_group = add_migration_commands() |
| 200 | + |
| 201 | + # Use a minimal command that doesn't require database setup |
| 202 | + # but still needs the config to be loaded successfully |
| 203 | + result = cli_runner.invoke(cli_group, ["--config", "external_config.config", "--help"]) |
| 204 | + |
| 205 | + # Should succeed without import errors |
| 206 | + assert result.exit_code == 0 |
| 207 | + assert "Error loading config" not in result.output |
| 208 | + assert "No module named" not in result.output |
| 209 | + |
| 210 | + finally: |
| 211 | + os.chdir(original_cwd) |
| 212 | + |
| 213 | + |
| 214 | +def test_external_config_loading_multiple_configs(cli_runner: CliRunner) -> None: |
| 215 | + """Test loading multiple configs from external module.""" |
| 216 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 217 | + temp_path = Path(temp_dir) |
| 218 | + |
| 219 | + # Create an external config file with multiple configs |
| 220 | + config_file = temp_path / "multi_config.py" |
| 221 | + config_file.write_text(""" |
| 222 | +from advanced_alchemy.config import SQLAlchemyAsyncConfig |
| 223 | +
|
| 224 | +configs = [ |
| 225 | + SQLAlchemyAsyncConfig( |
| 226 | + connection_string="sqlite+aiosqlite:///:memory:", |
| 227 | + bind_key="primary", |
| 228 | + ), |
| 229 | + SQLAlchemyAsyncConfig( |
| 230 | + connection_string="sqlite+aiosqlite:///:memory:", |
| 231 | + bind_key="secondary", |
| 232 | + ), |
| 233 | +] |
| 234 | +""") |
| 235 | + |
| 236 | + # Change to the temp directory |
| 237 | + original_cwd = os.getcwd() |
| 238 | + try: |
| 239 | + os.chdir(temp_dir) |
| 240 | + |
| 241 | + cli_group = add_migration_commands() |
| 242 | + result = cli_runner.invoke(cli_group, ["--config", "multi_config.configs", "--help"]) |
| 243 | + |
| 244 | + # Should succeed without import errors |
| 245 | + assert result.exit_code == 0 |
| 246 | + assert "Error loading config" not in result.output |
| 247 | + assert "No module named" not in result.output |
| 248 | + |
| 249 | + finally: |
| 250 | + os.chdir(original_cwd) |
| 251 | + |
| 252 | + |
| 253 | +def test_external_config_loading_nonexistent_module(cli_runner: CliRunner) -> None: |
| 254 | + """Test appropriate error when external module doesn't exist.""" |
| 255 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 256 | + # Change to empty temp directory |
| 257 | + original_cwd = os.getcwd() |
| 258 | + try: |
| 259 | + os.chdir(temp_dir) |
| 260 | + |
| 261 | + cli_group = add_migration_commands() |
| 262 | + # Use actual command to trigger config loading, not --help |
| 263 | + result = cli_runner.invoke(cli_group, ["--config", "nonexistent_module.config", "show-current-revision"]) |
| 264 | + |
| 265 | + # Should fail with appropriate error |
| 266 | + assert result.exit_code == 1 |
| 267 | + assert "Error loading config" in result.output |
| 268 | + assert "No module named 'nonexistent_module'" in result.output |
| 269 | + |
| 270 | + finally: |
| 271 | + os.chdir(original_cwd) |
| 272 | + |
| 273 | + |
| 274 | +def test_external_config_loading_nonexistent_attribute(cli_runner: CliRunner) -> None: |
| 275 | + """Test appropriate error when module exists but attribute doesn't.""" |
| 276 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 277 | + temp_path = Path(temp_dir) |
| 278 | + |
| 279 | + # Create an external config file without the expected attribute |
| 280 | + config_file = temp_path / "bad_config.py" |
| 281 | + config_file.write_text(""" |
| 282 | +# This module exists but doesn't have a 'missing_attr' attribute |
| 283 | +from advanced_alchemy.config import SQLAlchemyAsyncConfig |
| 284 | +
|
| 285 | +some_other_var = "not a config" |
| 286 | +""") |
| 287 | + |
| 288 | + # Change to the temp directory |
| 289 | + original_cwd = os.getcwd() |
| 290 | + try: |
| 291 | + os.chdir(temp_dir) |
| 292 | + |
| 293 | + cli_group = add_migration_commands() |
| 294 | + # Use actual command to trigger config loading, not --help |
| 295 | + result = cli_runner.invoke(cli_group, ["--config", "bad_config.missing_attr", "show-current-revision"]) |
| 296 | + |
| 297 | + # Should fail with appropriate error |
| 298 | + assert result.exit_code == 1 |
| 299 | + assert "Error loading config" in result.output |
| 300 | + # The actual error message may vary, but it should indicate the attribute issue |
| 301 | + |
| 302 | + finally: |
| 303 | + os.chdir(original_cwd) |
0 commit comments