Skip to content

Commit 3c0fa9c

Browse files
committed
tests/cmd(test[GitSubmodule]): add tests for submodule operations
why: Validate GitSubmoduleManager and GitSubmoduleEntryCmd functionality what: - Add submodule_repo fixture for creating submodule source repos - Add _setup_submodule_test helper to configure file protocol - Test GitSubmoduleManager methods: add, ls, get, filter, init, update, sync, summary, foreach - Test GitSubmoduleEntryCmd methods: status, init, update - Test GitSubmodule dataclass properties - Test ObjectDoesNotExist raised when submodule not found
1 parent 68a93c9 commit 3c0fa9c

File tree

1 file changed

+264
-0
lines changed

1 file changed

+264
-0
lines changed

tests/cmd/test_git.py

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,3 +1542,267 @@ def test_reflog_expire(git_repo: GitSync) -> None:
15421542
# Expire with dry_run should succeed
15431543
result = git_repo.cmd.reflog.expire(dry_run=True)
15441544
assert result == "" or "error" not in result.lower()
1545+
1546+
1547+
# GitSubmodule tests
1548+
# ==================
1549+
1550+
1551+
@pytest.fixture
1552+
def submodule_repo(
1553+
tmp_path: pathlib.Path,
1554+
git_commit_envvars: dict[str, str],
1555+
set_gitconfig: pathlib.Path,
1556+
) -> git.Git:
1557+
"""Create a git repository to use as a submodule source."""
1558+
import os
1559+
1560+
# Create a repo to serve as submodule source
1561+
source_path = tmp_path / "submodule_source"
1562+
source_path.mkdir()
1563+
source_repo = git.Git(path=source_path)
1564+
source_repo.init()
1565+
1566+
# Create initial commit with environment
1567+
env = os.environ.copy()
1568+
env.update(git_commit_envvars)
1569+
1570+
(source_path / "lib.py").write_text("# Library code\n")
1571+
source_repo.run(["add", "."])
1572+
source_repo.run(
1573+
["commit", "-m", "Initial commit"],
1574+
env=env,
1575+
)
1576+
1577+
return source_repo
1578+
1579+
1580+
def _setup_submodule_test(git_repo: GitSync, submodule_repo: git.Git) -> str:
1581+
"""Set up git_repo for submodule tests.
1582+
1583+
Returns the result of adding the submodule.
1584+
"""
1585+
# Allow file protocol for submodule operations
1586+
git_repo.cmd.run(["config", "protocol.file.allow", "always"])
1587+
1588+
# Add the submodule
1589+
return git_repo.cmd.submodules.add(
1590+
repository=str(submodule_repo.path),
1591+
path="vendor/lib",
1592+
)
1593+
1594+
1595+
def test_submodule_add(
1596+
git_repo: GitSync,
1597+
submodule_repo: git.Git,
1598+
) -> None:
1599+
"""Test GitSubmoduleManager.add()."""
1600+
# Allow file protocol for submodule operations
1601+
git_repo.cmd.run(["config", "protocol.file.allow", "always"])
1602+
1603+
# Add the submodule
1604+
result = git_repo.cmd.submodules.add(
1605+
repository=str(submodule_repo.path),
1606+
path="vendor/lib",
1607+
)
1608+
# Should succeed (output varies by git version)
1609+
assert "fatal" not in result.lower() or result == ""
1610+
1611+
1612+
def test_submodule_ls(
1613+
git_repo: GitSync,
1614+
submodule_repo: git.Git,
1615+
) -> None:
1616+
"""Test GitSubmoduleManager.ls()."""
1617+
# Setup
1618+
_setup_submodule_test(git_repo, submodule_repo)
1619+
1620+
# List submodules
1621+
submodules = git_repo.cmd.submodules.ls()
1622+
assert isinstance(submodules, list)
1623+
assert len(submodules) >= 1
1624+
1625+
# Check the submodule has expected attributes
1626+
submodule = submodules[0]
1627+
assert submodule.path == "vendor/lib"
1628+
assert submodule.name is not None
1629+
1630+
1631+
def test_submodule_get(
1632+
git_repo: GitSync,
1633+
submodule_repo: git.Git,
1634+
) -> None:
1635+
"""Test GitSubmoduleManager.get()."""
1636+
# Setup
1637+
_setup_submodule_test(git_repo, submodule_repo)
1638+
1639+
# Get the submodule by path
1640+
submodule = git_repo.cmd.submodules.get(path="vendor/lib")
1641+
assert submodule is not None
1642+
assert submodule.path == "vendor/lib"
1643+
1644+
1645+
def test_submodule_get_not_found(
1646+
git_repo: GitSync,
1647+
) -> None:
1648+
"""Test GitSubmoduleManager.get() raises when not found."""
1649+
# Try to get a non-existent submodule
1650+
with pytest.raises(ObjectDoesNotExist):
1651+
git_repo.cmd.submodules.get(path="nonexistent")
1652+
1653+
1654+
def test_submodule_filter(
1655+
git_repo: GitSync,
1656+
submodule_repo: git.Git,
1657+
) -> None:
1658+
"""Test GitSubmoduleManager.filter()."""
1659+
# Setup
1660+
_setup_submodule_test(git_repo, submodule_repo)
1661+
1662+
# Filter by path
1663+
submodules = git_repo.cmd.submodules.filter(path="vendor/lib")
1664+
assert len(submodules) == 1
1665+
assert submodules[0].path == "vendor/lib"
1666+
1667+
# Filter with no match
1668+
submodules = git_repo.cmd.submodules.filter(path="nonexistent")
1669+
assert len(submodules) == 0
1670+
1671+
1672+
def test_submodule_init(
1673+
git_repo: GitSync,
1674+
submodule_repo: git.Git,
1675+
) -> None:
1676+
"""Test GitSubmoduleManager.init()."""
1677+
# Setup
1678+
_setup_submodule_test(git_repo, submodule_repo)
1679+
1680+
# Initialize all submodules
1681+
result = git_repo.cmd.submodules.init()
1682+
assert result == "" or "fatal" not in result.lower()
1683+
1684+
1685+
def test_submodule_update(
1686+
git_repo: GitSync,
1687+
submodule_repo: git.Git,
1688+
) -> None:
1689+
"""Test GitSubmoduleManager.update()."""
1690+
# Setup
1691+
_setup_submodule_test(git_repo, submodule_repo)
1692+
1693+
# Update all submodules
1694+
result = git_repo.cmd.submodules.update(init=True)
1695+
assert "fatal" not in result.lower() or result == ""
1696+
1697+
1698+
def test_submodule_sync(
1699+
git_repo: GitSync,
1700+
submodule_repo: git.Git,
1701+
) -> None:
1702+
"""Test GitSubmoduleManager.sync()."""
1703+
# Setup
1704+
_setup_submodule_test(git_repo, submodule_repo)
1705+
1706+
# Sync submodule URLs
1707+
result = git_repo.cmd.submodules.sync()
1708+
assert result == "" or "fatal" not in result.lower()
1709+
1710+
1711+
def test_submodule_summary(
1712+
git_repo: GitSync,
1713+
submodule_repo: git.Git,
1714+
) -> None:
1715+
"""Test GitSubmoduleManager.summary()."""
1716+
# Setup
1717+
_setup_submodule_test(git_repo, submodule_repo)
1718+
1719+
# Get summary
1720+
result = git_repo.cmd.submodules.summary()
1721+
# Summary output may vary
1722+
assert isinstance(result, str)
1723+
1724+
1725+
def test_submodule_entry_status(
1726+
git_repo: GitSync,
1727+
submodule_repo: git.Git,
1728+
) -> None:
1729+
"""Test GitSubmoduleEntryCmd.status()."""
1730+
# Setup
1731+
_setup_submodule_test(git_repo, submodule_repo)
1732+
1733+
# Get the submodule and check status
1734+
submodule = git_repo.cmd.submodules.get(path="vendor/lib")
1735+
assert submodule.cmd is not None
1736+
1737+
result = submodule.cmd.status()
1738+
assert isinstance(result, str)
1739+
1740+
1741+
def test_submodule_entry_init(
1742+
git_repo: GitSync,
1743+
submodule_repo: git.Git,
1744+
) -> None:
1745+
"""Test GitSubmoduleEntryCmd.init()."""
1746+
# Setup
1747+
_setup_submodule_test(git_repo, submodule_repo)
1748+
1749+
# Get the submodule and init it
1750+
submodule = git_repo.cmd.submodules.get(path="vendor/lib")
1751+
assert submodule.cmd is not None
1752+
1753+
result = submodule.cmd.init()
1754+
assert result == "" or "fatal" not in result.lower()
1755+
1756+
1757+
def test_submodule_entry_update(
1758+
git_repo: GitSync,
1759+
submodule_repo: git.Git,
1760+
) -> None:
1761+
"""Test GitSubmoduleEntryCmd.update()."""
1762+
# Setup
1763+
_setup_submodule_test(git_repo, submodule_repo)
1764+
1765+
# Get the submodule and init it
1766+
submodule = git_repo.cmd.submodules.get(path="vendor/lib")
1767+
assert submodule.cmd is not None
1768+
1769+
# Init and update
1770+
submodule.cmd.init()
1771+
result = submodule.cmd.update()
1772+
assert "fatal" not in result.lower() or result == ""
1773+
1774+
1775+
def test_submodule_foreach(
1776+
git_repo: GitSync,
1777+
submodule_repo: git.Git,
1778+
) -> None:
1779+
"""Test GitSubmoduleManager.foreach()."""
1780+
# Setup
1781+
_setup_submodule_test(git_repo, submodule_repo)
1782+
1783+
# Run foreach with a simple command
1784+
result = git_repo.cmd.submodules.foreach(command="pwd")
1785+
assert isinstance(result, str)
1786+
1787+
1788+
def test_submodule_dataclass_properties(
1789+
git_repo: GitSync,
1790+
submodule_repo: git.Git,
1791+
) -> None:
1792+
"""Test GitSubmodule dataclass properties."""
1793+
# Setup
1794+
_setup_submodule_test(git_repo, submodule_repo)
1795+
1796+
# Get the submodule
1797+
submodule = git_repo.cmd.submodules.get(path="vendor/lib")
1798+
1799+
# Check dataclass attributes
1800+
assert submodule.path == "vendor/lib"
1801+
assert submodule.name is not None
1802+
assert submodule.url is not None
1803+
assert submodule.sha is not None or submodule.status_prefix == "-"
1804+
assert submodule.cmd is not None
1805+
1806+
# Test initialized property
1807+
# After add, submodule should be initialized (prefix not '-')
1808+
assert submodule.initialized is True or submodule.status_prefix == "-"

0 commit comments

Comments
 (0)