Skip to content

Commit baf5407

Browse files
committed
Add tests for all coverage gaps, reach 100% on macOS
- TestBestPrefixInvalidSystem: cover line 514 (bad system= arg) - TestSystemPropertyInvalidBase: cover line 317 (invalid _base) - TestQueryDeviceCapacityWindowsBody: cover lines 1358-1397 via mock.patch(create=True) injecting ctypes/msvcrt — runs on all platforms - TestQueryCapacityWindowsDriveLetterMock: cover lines 1549-1551 via mocked os.name='nt' and shutil.disk_usage — runs on all platforms - Lines 65-68: add # pragma: no cover to elif os.name == 'nt': import block (import-time, cannot be covered without module reload) Local result: 319 passed, 2 skipped, TOTAL 100% coverage, pylint 10.00/10
1 parent 221e920 commit baf5407

5 files changed

Lines changed: 96 additions & 2 deletions

File tree

bitmath/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
if os.name == 'posix':
6363
import stat
6464
import fcntl
65-
elif os.name == 'nt':
65+
elif os.name == 'nt': # pragma: no cover
6666
import ctypes
6767
import ctypes.wintypes
6868
import msvcrt # pylint: disable=import-error

tests/test_best_prefix_BASE.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,10 @@ def test_best_prefix_negative_huge_numbers(self):
9999
self.assertIs(type(negative_result), type(positive_result))
100100
# Verify that type is what we expect it to be
101101
self.assertIs(type(negative_result), bitmath.MiB)
102+
103+
104+
class TestBestPrefixInvalidSystem(TestCase):
105+
def test_best_prefix_invalid_system_raises(self):
106+
"""best_prefix raises ValueError when an invalid system constant is passed"""
107+
with self.assertRaises(ValueError):
108+
bitmath.best_prefix(bitmath.MiB(1), system="bogus")

tests/test_properties.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,12 @@ def test_Zib_property(self):
7373
def test_Yib_property(self):
7474
"""Yib property returns a Yib instance"""
7575
self.assertIsInstance(self.kib.Yib, bitmath.Yib)
76+
77+
78+
class TestSystemPropertyInvalidBase(TestCase):
79+
def test_system_property_invalid_base_raises(self):
80+
"""system property raises ValueError when _base is not 2 or 10"""
81+
obj = bitmath.MiB(1)
82+
obj._base = 7
83+
with self.assertRaises(ValueError):
84+
_ = obj.system

tests/test_query_capacity.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
import os
3232
import pathlib
33-
from unittest import skipUnless
33+
from unittest import mock, skipUnless
3434

3535
import bitmath
3636
from bitmath import Bitmath, Byte, Capacity
@@ -125,3 +125,19 @@ def test_query_capacity_windows_pathlike_drive_letter(self):
125125
result = bitmath.query_capacity(pathlib.PureWindowsPath("C:"))
126126
self.assertIsInstance(result, Capacity)
127127
self.assertGreater(result.total.bytes, 0)
128+
129+
130+
class TestQueryCapacityWindowsDriveLetterMock(TestCase):
131+
def test_query_capacity_windows_drive_letter_normalization_mock(self):
132+
"""query_capacity normalizes a bare drive letter via mocked os.name='nt'"""
133+
mock_usage = mock.MagicMock()
134+
mock_usage.total = 1_000_000_000_000
135+
mock_usage.used = 500_000_000_000
136+
mock_usage.free = 500_000_000_000
137+
138+
with mock.patch('bitmath.os.name', 'nt'):
139+
with mock.patch('bitmath.shutil.disk_usage', return_value=mock_usage) as mock_du:
140+
result = bitmath.query_capacity("c:")
141+
142+
self.assertIsInstance(result, Capacity)
143+
mock_du.assert_called_once_with("C:\\")

tests/test_query_device_capacity.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131

3232
from . import TestCase
3333
import bitmath
34+
import ctypes as real_ctypes
3435
import os
36+
import types
3537
from unittest import mock, skipUnless
3638
import struct
3739
from contextlib import ExitStack, contextmanager
@@ -133,3 +135,63 @@ def test_query_device_capacity_unsupported_platform_fails(self):
133135
with mock.patch('bitmath.os.name', unsupported):
134136
with self.assertRaises(NotImplementedError):
135137
bitmath.query_device_capacity(device)
138+
139+
140+
class TestQueryDeviceCapacityWindowsBody(TestCase):
141+
"""Mock-based tests for _query_device_capacity_windows body.
142+
143+
Run on all platforms by injecting ctypes and msvcrt into the bitmath
144+
namespace via mock.patch(..., create=True).
145+
"""
146+
147+
def _make_mock_ctypes(self):
148+
mc = types.SimpleNamespace(
149+
Structure=real_ctypes.Structure,
150+
c_longlong=real_ctypes.c_longlong,
151+
c_uint=real_ctypes.c_uint,
152+
c_ulong=real_ctypes.c_ulong,
153+
c_byte=real_ctypes.c_byte,
154+
byref=real_ctypes.byref,
155+
sizeof=real_ctypes.sizeof,
156+
wintypes=types.SimpleNamespace(DWORD=real_ctypes.c_ulong),
157+
windll=mock.MagicMock(),
158+
)
159+
mc.windll.kernel32.DeviceIoControl.return_value = 1
160+
return mc
161+
162+
def _make_mock_msvcrt(self):
163+
return types.SimpleNamespace(get_osfhandle=mock.Mock(return_value=999))
164+
165+
def _make_windows_device(self):
166+
fd = mock.MagicMock()
167+
fd.name = r'\\.\PhysicalDrive0'
168+
fd.fileno.return_value = 4
169+
return fd
170+
171+
def test_windows_body_success(self):
172+
"""_query_device_capacity_windows succeeds via mocked ctypes and msvcrt"""
173+
mock_ctypes = self._make_mock_ctypes()
174+
mock_msvcrt = self._make_mock_msvcrt()
175+
device_fd = self._make_windows_device()
176+
177+
with mock.patch('bitmath.ctypes', mock_ctypes, create=True):
178+
with mock.patch('bitmath.msvcrt', mock_msvcrt, create=True):
179+
result = bitmath._query_device_capacity_windows(device_fd)
180+
181+
# DiskSize is 0 by default — mock DeviceIoControl does not fill the struct
182+
self.assertEqual(result, 0)
183+
mock_msvcrt.get_osfhandle.assert_called_once_with(4)
184+
mock_ctypes.windll.kernel32.DeviceIoControl.assert_called_once()
185+
186+
def test_windows_body_ioctl_failure_raises_oserror(self):
187+
"""_query_device_capacity_windows raises OSError when DeviceIoControl fails"""
188+
mock_ctypes = self._make_mock_ctypes()
189+
mock_ctypes.windll.kernel32.DeviceIoControl.return_value = 0
190+
mock_ctypes.windll.kernel32.GetLastError.return_value = 5
191+
mock_msvcrt = self._make_mock_msvcrt()
192+
device_fd = self._make_windows_device()
193+
194+
with mock.patch('bitmath.ctypes', mock_ctypes, create=True):
195+
with mock.patch('bitmath.msvcrt', mock_msvcrt, create=True):
196+
with self.assertRaises(OSError):
197+
bitmath._query_device_capacity_windows(device_fd)

0 commit comments

Comments
 (0)