Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions humanfriendly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -656,9 +656,9 @@ def __init__(self, start_time=None, resumable=False):
if resumable:
self.monotonic = True
self.resumable = True
self.start_time = 0.0
self.start_time = None
self.total_time = 0.0
elif start_time:
elif start_time is not None:
self.monotonic = False
self.resumable = False
self.start_time = start_time
Expand Down Expand Up @@ -687,9 +687,9 @@ def __exit__(self, exc_type=None, exc_value=None, traceback=None):
"""
if not self.resumable:
raise ValueError("Timer is not resumable!")
if self.start_time:
if self.start_time is not None:
self.total_time += monotonic() - self.start_time
self.start_time = 0.0
self.start_time = None

def sleep(self, seconds):
"""
Expand Down Expand Up @@ -725,7 +725,7 @@ def elapsed_time(self):
elapsed_time = 0
if self.resumable:
elapsed_time += self.total_time
if self.start_time:
if self.start_time is not None:
current_time = monotonic() if self.monotonic else time.time()
elapsed_time += current_time - self.start_time
return elapsed_time
Expand Down
41 changes: 41 additions & 0 deletions humanfriendly/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,47 @@ def test_split(self):
self.assertEqual(split('foo, bar, baz'), ['foo', 'bar', 'baz'])
self.assertEqual(split('foo,bar,baz'), ['foo', 'bar', 'baz'])

def test_timer_epoch_start(self):
"""An explicit epoch start uses the wall clock, including zero."""
with PatchedAttribute(time, 'time', lambda: 12.5):
for start in (0, 0.0, -2.0, 2.0):
timer = Timer(start_time=start)
self.assertFalse(timer.monotonic)
self.assertEqual(timer.elapsed_time, 12.5 - start)

def test_timer_zero_monotonic_start(self):
"""A zero monotonic reading remains an active timer."""
with PatchedItem(Timer.__init__.__globals__, 'monotonic', lambda: 0.0):
automatic = Timer()
resumable = Timer(resumable=True)
resumable.__enter__()
with PatchedItem(Timer.__init__.__globals__, 'monotonic', lambda: 2.5):
self.assertEqual(automatic.elapsed_time, 2.5)
self.assertEqual(resumable.elapsed_time, 2.5)
resumable.__exit__(None, None, None)
self.assertEqual(resumable.elapsed_time, 2.5)
with PatchedItem(Timer.__init__.__globals__, 'monotonic', lambda: 4.0):
self.assertEqual(resumable.elapsed_time, 2.5)

def test_timer_inactive_and_resumed(self):
"""Paused timers stay fixed and resume accumulating elapsed time."""
with PatchedItem(Timer.__init__.__globals__, 'monotonic', lambda: 5.0):
timer = Timer(resumable=True)
self.assertEqual(timer.elapsed_time, 0)
timer.__exit__(None, None, None)
self.assertEqual(timer.elapsed_time, 0)
self.assertIs(timer.__enter__(), timer)
with PatchedItem(Timer.__init__.__globals__, 'monotonic', lambda: 7.0):
timer.__exit__(None, None, None)
self.assertEqual(timer.elapsed_time, 2.0)
timer.__exit__(None, None, None)
self.assertEqual(timer.elapsed_time, 2.0)
timer.__enter__()
with PatchedItem(Timer.__init__.__globals__, 'monotonic', lambda: 10.0):
self.assertEqual(timer.elapsed_time, 5.0)
timer.__exit__(None, None, None)
self.assertEqual(timer.elapsed_time, 5.0)

def test_timer(self):
"""Test :func:`humanfriendly.Timer`."""
for seconds, text in ((1, '1 second'),
Expand Down