luminos/tests/test_disk.py
Jeff Smith 6875cf5ed1 feat(tests): add unit test coverage for all testable modules (#37)
129 tests across cache, filetypes, code, disk, recency, tree, report,
and capabilities. Uses stdlib unittest only — no new dependencies.
Also updates CLAUDE.md development workflow to require test coverage
for all future changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 16:57:26 -06:00

105 lines
3.7 KiB
Python

"""Tests for luminos_lib/disk.py"""
import unittest
from unittest.mock import patch, MagicMock
from luminos_lib.disk import _human_size, top_directories, get_disk_usage
class TestHumanSize(unittest.TestCase):
def test_bytes(self):
self.assertEqual(_human_size(512), "512 B")
def test_kilobytes(self):
self.assertEqual(_human_size(1024), "1.0 KB")
def test_megabytes(self):
self.assertEqual(_human_size(1024 * 1024), "1.0 MB")
def test_gigabytes(self):
self.assertEqual(_human_size(1024 ** 3), "1.0 GB")
def test_terabytes(self):
self.assertEqual(_human_size(1024 ** 4), "1.0 TB")
def test_zero_bytes(self):
self.assertEqual(_human_size(0), "0 B")
def test_fractional_kb(self):
result = _human_size(1536) # 1.5 KB
self.assertEqual(result, "1.5 KB")
class TestTopDirectories(unittest.TestCase):
def _entries(self, sizes):
return [{"path": f"/dir{i}", "size_bytes": s, "size_human": _human_size(s)}
for i, s in enumerate(sizes)]
def test_returns_top_n(self):
entries = self._entries([100, 500, 200, 800, 300, 50])
top = top_directories(entries, n=3)
self.assertEqual(len(top), 3)
self.assertEqual(top[0]["size_bytes"], 800)
self.assertEqual(top[1]["size_bytes"], 500)
self.assertEqual(top[2]["size_bytes"], 300)
def test_fewer_than_n_entries(self):
entries = self._entries([100, 200])
top = top_directories(entries, n=5)
self.assertEqual(len(top), 2)
def test_empty(self):
self.assertEqual(top_directories([], n=5), [])
def test_default_n_is_five(self):
entries = self._entries([i * 100 for i in range(10)])
top = top_directories(entries)
self.assertEqual(len(top), 5)
class TestGetDiskUsage(unittest.TestCase):
def _mock_du(self, output, returncode=0):
return MagicMock(returncode=returncode, stdout=output)
def test_parses_du_output(self):
du_output = "4096\t/tmp/mydir\n1024\t/tmp/mydir/sub\n"
with patch("subprocess.run", return_value=self._mock_du(du_output)):
result = get_disk_usage("/tmp/mydir")
self.assertEqual(len(result), 2)
self.assertEqual(result[0]["size_bytes"], 4096)
self.assertEqual(result[0]["path"], "/tmp/mydir")
def test_skips_hidden_dirs_by_default(self):
du_output = "1024\t/tmp/mydir/.git\n2048\t/tmp/mydir\n"
with patch("subprocess.run", return_value=self._mock_du(du_output)):
result = get_disk_usage("/tmp/mydir")
paths = [r["path"] for r in result]
self.assertNotIn("/tmp/mydir/.git", paths)
def test_includes_hidden_dirs_when_requested(self):
du_output = "1024\t/tmp/mydir/.git\n2048\t/tmp/mydir\n"
with patch("subprocess.run", return_value=self._mock_du(du_output)):
result = get_disk_usage("/tmp/mydir", show_hidden=True)
paths = [r["path"] for r in result]
self.assertIn("/tmp/mydir/.git", paths)
def test_timeout_returns_empty(self):
import subprocess
with patch("subprocess.run", side_effect=subprocess.TimeoutExpired("du", 30)):
result = get_disk_usage("/tmp/mydir")
self.assertEqual(result, [])
def test_file_not_found_returns_empty(self):
with patch("subprocess.run", side_effect=FileNotFoundError):
result = get_disk_usage("/tmp/mydir")
self.assertEqual(result, [])
def test_size_human_is_populated(self):
du_output = "1048576\t/tmp/mydir\n"
with patch("subprocess.run", return_value=self._mock_du(du_output)):
result = get_disk_usage("/tmp/mydir")
self.assertEqual(result[0]["size_human"], "1.0 MB")
if __name__ == "__main__":
unittest.main()