Skip to content

Commit 37c22ef

Browse files
committed
tests/cmd(test[GitStash]): add tests for stash operations
why: Verify GitStashManager and GitStashEntryCmd methods work correctly what: - Add tests for push, ls, show, apply, pop, drop, clear, create_branch - Add StashApplyPopFixture with NamedTuple + test_id pattern - Clear stashes at test start to avoid interference from previous tests - All tests use pytest fixtures (no mocks)
1 parent 3de8064 commit 37c22ef

1 file changed

Lines changed: 218 additions & 0 deletions

File tree

tests/cmd/test_git.py

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,3 +879,221 @@ def test_tag_verify_unsigned(git_repo: GitSync) -> None:
879879

880880
# verify on unsigned tag should return error message
881881
assert "error" in result.lower() or "cannot verify" in result.lower()
882+
883+
884+
# =============================================================================
885+
# GitStashManager / GitStashEntryCmd Tests
886+
# =============================================================================
887+
888+
889+
def test_stash_push_and_list(git_repo: GitSync) -> None:
890+
"""Test GitStashManager.push() and ls()."""
891+
# Create a file and modify it to have something to stash
892+
test_file = git_repo.path / "stash_test.txt"
893+
test_file.write_text("initial content")
894+
git_repo.cmd.run(["add", "stash_test.txt"])
895+
git_repo.cmd.run(["commit", "-m", "Add test file"])
896+
897+
# Modify the file
898+
test_file.write_text("modified content")
899+
900+
# Push to stash
901+
result = git_repo.cmd.stashes.push(message="Test stash")
902+
903+
# Should succeed (not "No local changes")
904+
assert "no local changes" not in result.lower()
905+
906+
# List stashes
907+
stashes = git_repo.cmd.stashes.ls()
908+
assert len(stashes) >= 1
909+
assert stashes[0].index == 0
910+
911+
912+
def test_stash_entry_show(git_repo: GitSync) -> None:
913+
"""Test GitStashEntryCmd.show()."""
914+
# Create a stash first
915+
test_file = git_repo.path / "show_test.txt"
916+
test_file.write_text("initial content")
917+
git_repo.cmd.run(["add", "show_test.txt"])
918+
git_repo.cmd.run(["commit", "-m", "Add test file"])
919+
920+
test_file.write_text("modified for stash")
921+
git_repo.cmd.stashes.push(message="Show test stash")
922+
923+
# Get stash and show
924+
stash = git_repo.cmd.stashes.get(index=0)
925+
assert stash is not None
926+
927+
result = stash.show()
928+
929+
# show should display diff info
930+
assert "show_test.txt" in result or len(result) > 0
931+
932+
933+
class StashApplyPopFixture(t.NamedTuple):
934+
"""Test fixture for GitStashEntryCmd apply/pop operations."""
935+
936+
test_id: str
937+
method: str # "apply" or "pop"
938+
removes_stash: bool
939+
940+
941+
STASH_APPLY_POP_FIXTURES: list[StashApplyPopFixture] = [
942+
StashApplyPopFixture(
943+
test_id="apply-stash",
944+
method="apply",
945+
removes_stash=False,
946+
),
947+
StashApplyPopFixture(
948+
test_id="pop-stash",
949+
method="pop",
950+
removes_stash=True,
951+
),
952+
]
953+
954+
955+
@pytest.mark.parametrize(
956+
list(StashApplyPopFixture._fields),
957+
STASH_APPLY_POP_FIXTURES,
958+
ids=[test.test_id for test in STASH_APPLY_POP_FIXTURES],
959+
)
960+
def test_stash_apply_pop(
961+
git_repo: GitSync,
962+
test_id: str,
963+
method: str,
964+
removes_stash: bool,
965+
) -> None:
966+
"""Test GitStashEntryCmd.apply() and pop()."""
967+
# Clear any existing stashes
968+
git_repo.cmd.stashes.clear()
969+
970+
# Create a stash first
971+
test_file = git_repo.path / f"{test_id}_test.txt"
972+
test_file.write_text("initial content")
973+
git_repo.cmd.run(["add", f"{test_id}_test.txt"])
974+
git_repo.cmd.run(["commit", "-m", "Add test file"])
975+
976+
test_file.write_text("modified for stash")
977+
git_repo.cmd.stashes.push(message=f"Test {method}")
978+
979+
# Get stash
980+
stash = git_repo.cmd.stashes.get(index=0)
981+
assert stash is not None
982+
983+
# Apply or pop
984+
if method == "apply":
985+
result = stash.apply()
986+
else:
987+
result = stash.pop()
988+
989+
# Should succeed
990+
assert "error" not in result.lower() or "conflict" in result.lower()
991+
992+
# Check if stash was removed
993+
stashes_after = git_repo.cmd.stashes.ls()
994+
if removes_stash:
995+
assert len(stashes_after) == 0
996+
else:
997+
assert len(stashes_after) >= 1
998+
999+
1000+
def test_stash_drop(git_repo: GitSync) -> None:
1001+
"""Test GitStashEntryCmd.drop()."""
1002+
# Clear any existing stashes
1003+
git_repo.cmd.stashes.clear()
1004+
1005+
# Create a stash first
1006+
test_file = git_repo.path / "drop_test.txt"
1007+
test_file.write_text("initial content")
1008+
git_repo.cmd.run(["add", "drop_test.txt"])
1009+
git_repo.cmd.run(["commit", "-m", "Add test file"])
1010+
1011+
test_file.write_text("modified for stash")
1012+
git_repo.cmd.stashes.push(message="Drop test stash")
1013+
1014+
# Verify stash exists
1015+
stashes = git_repo.cmd.stashes.ls()
1016+
assert len(stashes) == 1
1017+
1018+
# Get stash and drop
1019+
stash = git_repo.cmd.stashes.get(index=0)
1020+
assert stash is not None
1021+
1022+
result = stash.drop()
1023+
assert "dropped" in result.lower()
1024+
1025+
# Verify stash is gone
1026+
stashes_after = git_repo.cmd.stashes.ls()
1027+
assert len(stashes_after) == 0
1028+
1029+
1030+
def test_stash_clear(git_repo: GitSync) -> None:
1031+
"""Test GitStashManager.clear()."""
1032+
# Create multiple stashes
1033+
test_file = git_repo.path / "clear_test.txt"
1034+
test_file.write_text("initial content")
1035+
git_repo.cmd.run(["add", "clear_test.txt"])
1036+
git_repo.cmd.run(["commit", "-m", "Add test file"])
1037+
1038+
# Create first stash
1039+
test_file.write_text("modified 1")
1040+
git_repo.cmd.stashes.push(message="First stash")
1041+
1042+
# Create second stash
1043+
test_file.write_text("modified 2")
1044+
git_repo.cmd.stashes.push(message="Second stash")
1045+
1046+
# Verify stashes exist
1047+
stashes = git_repo.cmd.stashes.ls()
1048+
assert len(stashes) >= 2
1049+
1050+
# Clear all stashes
1051+
result = git_repo.cmd.stashes.clear()
1052+
assert result == ""
1053+
1054+
# Verify all stashes are gone
1055+
stashes_after = git_repo.cmd.stashes.ls()
1056+
assert len(stashes_after) == 0
1057+
1058+
1059+
def test_stash_filter(git_repo: GitSync) -> None:
1060+
"""Test GitStashManager.filter() with QueryList filtering."""
1061+
# Create a stash on master branch
1062+
test_file = git_repo.path / "filter_test.txt"
1063+
test_file.write_text("initial content")
1064+
git_repo.cmd.run(["add", "filter_test.txt"])
1065+
git_repo.cmd.run(["commit", "-m", "Add test file"])
1066+
1067+
test_file.write_text("modified for stash")
1068+
git_repo.cmd.stashes.push(message="Filter test stash")
1069+
1070+
# Filter by branch
1071+
stashes = git_repo.cmd.stashes.filter(branch="master")
1072+
assert len(stashes) >= 1
1073+
1074+
1075+
def test_stash_entry_create_branch(git_repo: GitSync) -> None:
1076+
"""Test GitStashEntryCmd.create_branch()."""
1077+
# Create a stash first
1078+
test_file = git_repo.path / "branch_test.txt"
1079+
test_file.write_text("initial content")
1080+
git_repo.cmd.run(["add", "branch_test.txt"])
1081+
git_repo.cmd.run(["commit", "-m", "Add test file"])
1082+
1083+
test_file.write_text("modified for stash")
1084+
git_repo.cmd.stashes.push(message="Branch test stash")
1085+
1086+
# Get stash and create branch
1087+
stash = git_repo.cmd.stashes.get(index=0)
1088+
assert stash is not None
1089+
1090+
result = stash.create_branch("stash-branch")
1091+
1092+
# Should create branch and apply stash
1093+
assert "error" not in result.lower() or "already exists" in result.lower()
1094+
1095+
# Verify branch exists (or stash was applied)
1096+
branches = git_repo.cmd.branches.ls()
1097+
branch_names = [b.branch_name for b in branches]
1098+
# Either branch was created or we're on it
1099+
assert "stash-branch" in branch_names or "master" in branch_names

0 commit comments

Comments
 (0)