"""Tests for CLI commands.""" import sqlite3 import subprocess import sys import tempfile import pytest from src.db import _create_tables, add_repo class TestRepoFormatValidation: def test_valid_format(self): from src.cli import REPO_PATTERN assert REPO_PATTERN.match("owner/repo") assert REPO_PATTERN.match("my-org/my_repo") assert REPO_PATTERN.match("a.b/c-d_e") def test_invalid_format(self): from src.cli import REPO_PATTERN assert not REPO_PATTERN.match("owner") assert not REPO_PATTERN.match("repo") assert not REPO_PATTERN.match("owner/repo/extra") class TestParseSince: def test_hours(self): from src.cli import parse_since from datetime import timedelta assert parse_since("24h") == timedelta(hours=24) def test_days(self): from src.cli import parse_since from datetime import timedelta assert parse_since("2d") == timedelta(days=2) def test_minutes(self): from src.cli import parse_since from datetime import timedelta assert parse_since("30m") == timedelta(minutes=30) def test_invalid_defaults(self): from src.cli import parse_since from datetime import timedelta assert parse_since("invalid") == timedelta(hours=24) class TestCliHelp: def test_help_flag(self): result = subprocess.run( [sys.executable, "-m", "src.cli", "--help"], capture_output=True, text=True ) assert result.returncode == 0 assert "ghrel" in result.stdout.lower() or "track" in result.stdout.lower() def test_version_flag(self): result = subprocess.run( [sys.executable, "-m", "src.cli", "--version"], capture_output=True, text=True ) assert result.returncode == 0 assert "0.1.0" in result.stdout class TestCliList: def test_list_empty(self, tmp_path): db_path = str(tmp_path / "test.db") result = subprocess.run( [sys.executable, "-m", "src.cli", "--db-path", db_path, "list"], capture_output=True, text=True ) assert result.returncode == 0 assert "No repositories" in result.stdout class TestParseInterval: def test_seconds(self): from src.cli import parse_interval assert parse_interval("60s") == 60 def test_minutes(self): from src.cli import parse_interval assert parse_interval("30m") == 1800 def test_hours(self): from src.cli import parse_interval assert parse_interval("2h") == 7200 def test_days(self): from src.cli import parse_interval assert parse_interval("1d") == 86400 def test_invalid_format(self): from src.cli import parse_interval with pytest.raises(SystemExit): parse_interval("invalid") class TestCliDaemon: def test_daemon_help(self): result = subprocess.run( [sys.executable, "-m", "src.cli", "daemon", "--help"], capture_output=True, text=True ) assert result.returncode == 0 assert "interval" in result.stdout.lower() assert "pid-file" in result.stdout.lower() def test_daemon_pid_file_write(self, tmp_path): """Test that daemon PID file writing works correctly.""" import os from pathlib import Path pid_file = Path(tmp_path / "daemon.pid") pid_file.parent.mkdir(parents=True, exist_ok=True) # Test PID file writing logic directly pid_file.write_text(str(os.getpid())) assert pid_file.exists() assert pid_file.read_text() == str(os.getpid()) pid_file.unlink() assert not pid_file.exists() def test_cmd_check_for_daemon_empty(self, tmp_path): """Test daemon check with no repos (no error raised).""" db_path = str(tmp_path / "test.db") from src.cli import cmd_check_for_daemon cmd_check_for_daemon(db_path) # Should not raise class TestCliAddRemove: def test_add_invalid_format(self, tmp_path): db_path = str(tmp_path / "test.db") result = subprocess.run( [sys.executable, "-m", "src.cli", "--db-path", db_path, "add", "invalid"], capture_output=True, text=True ) assert result.returncode != 0 assert "Invalid repo format" in result.stderr