"""Tests for CLI commands.""" import os import sys import tempfile from pathlib import Path from unittest.mock import patch sys.path.insert(0, str(Path(__file__).parent.parent.parent)) import pytest from click.testing import CliRunner from gitignore_generator.cli import main from gitignore_generator import __version__ class TestCLI: """Tests for CLI commands.""" @pytest.fixture def runner(self): """Create CLI runner.""" return CliRunner() @pytest.fixture def temp_dir(self): """Create temporary directory.""" with tempfile.TemporaryDirectory() as tmpdir: orig_cwd = os.getcwd() os.chdir(tmpdir) yield Path(tmpdir) os.chdir(orig_cwd) def test_version_flag(self, runner): """Test --version flag.""" result = runner.invoke(main, ["--version"]) assert result.exit_code == 0 assert f"v{__version__}" in result.output def test_generate_command(self, runner, temp_dir): """Test generate command.""" result = runner.invoke(main, ["generate", "python"]) assert result.exit_code == 0 assert ".gitignore" in result.output def test_generate_multiple_templates(self, runner, temp_dir): """Test generating multiple templates.""" result = runner.invoke(main, ["generate", "python", "javascript"]) assert result.exit_code == 0 assert "successfully generated" in result.output.lower() assert ".gitignore" in result.output.lower() def test_generate_with_ide(self, runner, temp_dir): """Test generating with IDE template.""" result = runner.invoke(main, ["generate", "python", "--ide", "vscode"]) assert result.exit_code == 0 def test_generate_invalid_template(self, runner, temp_dir): """Test generate with invalid template.""" result = runner.invoke(main, ["generate", "nonexistent_template"]) assert result.exit_code != 0 assert "not found" in result.output.lower() def test_generate_with_output(self, runner, temp_dir): """Test generate with custom output file.""" result = runner.invoke(main, ["generate", "python", "-o", "custom.gitignore"]) assert result.exit_code == 0 assert os.path.exists("custom.gitignore") def test_list_command(self, runner): """Test list command.""" result = runner.invoke(main, ["list"]) assert result.exit_code == 0 assert "python" in result.output.lower() assert "javascript" in result.output.lower() def test_list_by_category(self, runner): """Test list by category.""" result = runner.invoke(main, ["list", "--category", "languages"]) assert result.exit_code == 0 def test_search_command(self, runner): """Test search command.""" result = runner.invoke(main, ["search", "python"]) assert result.exit_code == 0 assert "python" in result.output.lower() def test_search_no_results(self, runner): """Test search with no results.""" result = runner.invoke(main, ["search", "nonexistent12345"]) assert result.exit_code == 0 assert "no templates found" in result.output.lower() def test_validate_valid_file(self, runner, temp_dir): """Test validating a valid .gitignore file.""" Path(".gitignore").write_text("*.pyc\n__pycache__/\n") result = runner.invoke(main, ["validate", ".gitignore"]) assert result.exit_code == 0 assert "Valid" in result.output def test_validate_invalid_file(self, runner, temp_dir): """Test validating an invalid .gitignore file.""" Path(".gitignore").write_text("test\\n") result = runner.invoke(main, ["validate", ".gitignore"]) assert result.exit_code == 0 assert "Invalid" in result.output or "ERROR" in result.output def test_template_add(self, runner, temp_dir): """Test adding a custom template.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".gitignore", delete=False) as f: f.write("# Custom\ncustom.txt\n") temp_file = f.name try: result = runner.invoke(main, ["template-add", "my_template", temp_file]) assert result.exit_code == 0 assert "my_template" in result.output.lower() finally: os.unlink(temp_file) def test_template_remove(self, runner): """Test removing a custom template.""" result = runner.invoke(main, ["template-remove", "nonexistent"]) assert result.exit_code != 0 def test_template_export(self, runner, temp_dir): """Test exporting a template.""" result = runner.invoke(main, ["template-export", "python", "exported.gitignore"]) assert result.exit_code == 0 assert os.path.exists("exported.gitignore") def test_template_info(self, runner): """Test template info command.""" result = runner.invoke(main, ["info", "python"]) assert result.exit_code == 0 assert "python" in result.output.lower() assert "Patterns" in result.output or "Lines" in result.output def test_generate_overwrite_prompt(self, runner, temp_dir): """Test overwrite prompt for existing file.""" Path(".gitignore").write_text("old content") result = runner.invoke(main, ["generate", "python", "-f"]) assert result.exit_code == 0 def test_interactive_command_exists(self, runner): """Test interactive command exists.""" result = runner.invoke(main, ["--help"]) assert "interactive" in result.output.lower() def test_generate_no_templates_error(self, runner, temp_dir): """Test error when no templates specified.""" result = runner.invoke(main, ["generate"]) assert result.exit_code != 0 assert "no templates" in result.output.lower()