Skip to content

Commit

Permalink
Merge pull request #40 from juneHQ/vinayak/2025-01-24-fix-init-dir
Browse files Browse the repository at this point in the history
Remove cyclic dependency on directory init
  • Loading branch information
vinayak-mehta authored Jan 24, 2025
2 parents 895c394 + 2c39ce2 commit 8e5eac7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ Houseplant uses the following environment variables:
- ``CLICKHOUSE_PORT``: ClickHouse server port
- ``CLICKHOUSE_USER``: ClickHouse username
- ``CLICKHOUSE_PASSWORD``: ClickHouse password
- ``CLICKHOUSE_DATABASE``: ClickHouse database name
- ``CLICKHOUSE_DB``: ClickHouse database name
2 changes: 1 addition & 1 deletion src/houseplant/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def common(
@app.command()
def init():
"""Initialize a new houseplant project."""
hp = get_houseplant()
hp = Houseplant()
hp.init()


Expand Down
52 changes: 47 additions & 5 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,51 @@
from typing import Generator

import pytest
from typer.testing import CliRunner

from houseplant import Houseplant, __version__
from houseplant.cli import app
from typer.testing import CliRunner

runner = CliRunner()


@pytest.fixture(autouse=True)
def mock_clickhouse(mocker):
"""Mock ClickHouse connection and client for all tests."""
# Mock the clickhouse_driver.Client
mock_client = mocker.patch("houseplant.clickhouse_client.Client", autospec=True)

# Create a mock instance with required methods and attributes
client_instance = mocker.Mock()
client_instance.execute.return_value = [[1]] # Default successful response
client_instance.connection = mocker.Mock()
client_instance.connection.database = "test_db"
mock_client.return_value = client_instance

return client_instance


@pytest.fixture
def mock_houseplant(mocker) -> Generator[None, None, None]:
def mock_houseplant(mocker, mock_clickhouse) -> Generator[None, None, None]:
"""Mock the Houseplant class to avoid actual operations during testing."""
mock = mocker.patch("houseplant.cli.get_houseplant", autospec=True)
# Create a real instance to get access to the original init method
real_instance = Houseplant()

# Create mock instance
mock_instance = mocker.Mock(spec=Houseplant)
mock.return_value = mock_instance
mock_instance.db = mocker.Mock()
mock_instance.db.client = mock_clickhouse
mock_instance.db._check_clickhouse_connection.return_value = None
mock_instance.db.init_migrations_table.return_value = None
mock_instance.console = real_instance.console

# Create a mock that wraps the real init method
mock_instance.init = mocker.Mock(side_effect=real_instance.init)

# Mock both the constructor and get_houseplant
mocker.patch("houseplant.cli.Houseplant", return_value=mock_instance)
mocker.patch("houseplant.cli.get_houseplant", return_value=mock_instance)

yield mock_instance


Expand Down Expand Up @@ -46,12 +78,22 @@ def test_version_flag():
assert f"houseplant version {__version__}" in result.stdout


def test_init_command(mock_houseplant):
def test_init_command(tmp_path, mock_houseplant, monkeypatch):
"""Test the init command."""
# Change to temp directory safely using monkeypatch
monkeypatch.chdir(tmp_path)

result = runner.invoke(app, ["init"])
assert result.exit_code == 0
mock_houseplant.init.assert_called_once()

# Verify directories were created using absolute paths
migrations_dir = tmp_path / "ch" / "migrations"
schema_file = tmp_path / "ch" / "schema.sql"

assert migrations_dir.exists()
assert schema_file.exists()


def test_migrate_status_command(mock_houseplant):
"""Test the migrate:status command."""
Expand Down
18 changes: 18 additions & 0 deletions tests/test_houseplant.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,24 @@ def migration_with_settings(tmp_path):
return migration_content


def test_init(houseplant, tmp_path, mocker):
# Mock database calls
mock_init_migrations = mocker.patch.object(houseplant.db, "init_migrations_table")

# Change to temp directory
os.chdir(tmp_path)

# Run init
houseplant.init()

# Verify directories and files were created
assert os.path.exists("ch/migrations")
assert os.path.exists("ch/schema.sql")

# Verify migrations table was initialized
mock_init_migrations.assert_called_once()


def test_migration_with_settings(houseplant, migration_with_settings, mocker):
mock_execute = mocker.patch.object(houseplant.db.client, "execute")
settings = {"settings": {"enable_dynamic_type": 1, "max_table_size_to_drop": 0}}
Expand Down

0 comments on commit 8e5eac7

Please sign in to comment.