From 6d9ba405386cc1ceb39c07b085b83209c19527b6 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 22 Mar 2026 18:15:40 +0000 Subject: [PATCH] Initial upload: shell-history-semantic-search v0.1.0 --- tests/test_parsers.py | 143 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 tests/test_parsers.py diff --git a/tests/test_parsers.py b/tests/test_parsers.py new file mode 100644 index 0000000..940d5d5 --- /dev/null +++ b/tests/test_parsers.py @@ -0,0 +1,143 @@ +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 \ No newline at end of file