import pytest from pathlib import Path from shell_history_search.parsers import HistoryEntry from shell_history_search.parsers.bash import BashHistoryParser from shell_history_search.parsers.zsh import ZshHistoryParser from shell_history_search.parsers.fish import FishHistoryParser from shell_history_search.parsers.factory import get_parser, get_all_parsers class TestBashHistoryParser: def test_get_history_path(self, temp_home): parser = BashHistoryParser() assert parser.get_history_path() == temp_home / ".bash_history" def test_parse_history(self, sample_bash_history, temp_home): parser = BashHistoryParser() entries = list(parser.parse(sample_bash_history)) assert len(entries) == 7 assert all(e.shell_type == "bash" for e in entries) commands = [e.command for e in entries] assert "git add ." in commands assert "docker build -t myapp ." in commands assert all(e.command_hash for e in entries) assert all(e.timestamp is None for e in entries) def test_parse_empty_file(self, temp_home): history_file = temp_home / ".bash_history" history_file.write_text("") parser = BashHistoryParser() entries = list(parser.parse(history_file)) assert len(entries) == 0 def test_parse_nonexistent_file(self, temp_home): parser = BashHistoryParser() entries = list(parser.parse(temp_home / ".bash_history")) assert len(entries) == 0 class TestZshHistoryParser: def test_get_history_path(self, temp_home): parser = ZshHistoryParser() assert parser.get_history_path() == temp_home / ".zsh_history" def test_parse_history(self, sample_zsh_history, temp_home): parser = ZshHistoryParser() entries = list(parser.parse(sample_zsh_history)) assert len(entries) == 4 assert all(e.shell_type == "zsh" for e in entries) commands = [e.command for e in entries] assert "git pull origin main" in commands assert "pytest tests/ -v" in commands timestamps = [e.timestamp for e in entries] assert all(ts is not None for ts in timestamps) assert timestamps[0] == 1700000000 def test_parse_empty_file(self, temp_home): history_file = temp_home / ".zsh_history" history_file.write_text("") parser = ZshHistoryParser() entries = list(parser.parse(history_file)) assert len(entries) == 0 class TestFishHistoryParser: def test_get_history_path(self, temp_home): parser = FishHistoryParser() expected = temp_home / ".local" / "share" / "fish" / "fish_history" assert parser.get_history_path() == expected def test_parse_history(self, sample_fish_history, temp_home): parser = FishHistoryParser() entries = list(parser.parse(sample_fish_history)) assert len(entries) == 3 assert all(e.shell_type == "fish" for e in entries) commands = [e.command for e in entries] assert "docker-compose up -d" in commands assert "cargo build --release" in commands timestamps = [e.timestamp for e in entries] assert all(ts is not None for ts in timestamps) def test_parse_empty_file(self, temp_home): history_file = temp_home / ".local" / "share" / "fish" / "fish_history" history_file.parent.mkdir(parents=True, exist_ok=True) history_file.write_text("") parser = FishHistoryParser() entries = list(parser.parse(history_file)) assert len(entries) == 0 class TestParserFactory: def test_get_parser_bash(self): parser = get_parser("bash") assert isinstance(parser, BashHistoryParser) def test_get_parser_zsh(self): parser = get_parser("zsh") assert isinstance(parser, ZshHistoryParser) def test_get_parser_fish(self): parser = get_parser("fish") assert isinstance(parser, FishHistoryParser) def test_get_parser_case_insensitive(self): parser = get_parser("BASH") assert isinstance(parser, BashHistoryParser) def test_get_parser_invalid(self): with pytest.raises(ValueError, match="Unknown shell type"): get_parser("csh") def test_get_all_parsers(self): parsers = get_all_parsers() assert len(parsers) == 3 assert isinstance(parsers[0], BashHistoryParser) assert isinstance(parsers[1], ZshHistoryParser) assert isinstance(parsers[2], FishHistoryParser) class TestHistoryEntry: def test_create_hash(self): hash1 = HistoryEntry.create_hash("git add .") hash2 = HistoryEntry.create_hash("git add .") hash3 = HistoryEntry.create_hash("git commit") assert hash1 == hash2 assert hash1 != hash3 assert len(hash1) == 16