audio: Create a StopWatch object

The StopWatch will be used to calculate how long a track is in the
'playing' state so we can accurately determin if it has been played or
not.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2024-03-25 13:17:22 -04:00
parent c3818a2b18
commit db6ae0ecb6
2 changed files with 129 additions and 0 deletions

View File

@ -0,0 +1,42 @@
# Copyright 2024 (c) Anna Schumaker.
"""A custom StopWatch object for tracking play time."""
import datetime
from gi.repository import GObject
class StopWatch(GObject.GObject):
"""A StopWatch object."""
def __init__(self) -> None:
"""Initialize the StopWatch."""
super().__init__()
self._saved = None
self._started = None
def elapsed_time(self) -> float:
"""Get the elapsed time (in seconds)."""
total = datetime.timedelta()
if self._saved is not None:
total += self._saved
if self._started is not None:
total += datetime.datetime.now() - self._started
return total.total_seconds()
def reset(self) -> None:
"""Reset the StopWatch."""
self._saved = None
self._started = None
def start(self) -> None:
"""Start the StopWatch."""
self._started = datetime.datetime.now()
def stop(self) -> None:
"""Stop the StopWatch."""
if self._started is not None:
delta = datetime.datetime.now() - self._started
if self._saved is None:
self._saved = delta
else:
self._saved += delta
self._started = None

View File

@ -0,0 +1,87 @@
# Copyright 2024 (c) Anna Schumaker.
"""Tests our StopWatch object."""
import datetime
import emmental.audio.stopwatch
import unittest
from gi.repository import GObject
@unittest.mock.patch.object(emmental.audio.stopwatch, "datetime")
class TestStopwatch(unittest.TestCase):
"""Our stopwatch test case."""
def setUp(self):
"""Set up common variables."""
self.now = datetime.datetime.now()
self.newdelta = datetime.timedelta
self.stopwatch = emmental.audio.stopwatch.StopWatch()
def test_init(self, mock_datetime: unittest.mock.Mock):
"""Test that the StopWatch was created properly."""
self.assertIsInstance(self.stopwatch, GObject.GObject)
def test_elapsed_time(self, mock_datetime: unittest.mock.Mock):
"""Test the elapsed_time() function."""
mock_datetime.timedelta = self.newdelta
self.assertEqual(self.stopwatch.elapsed_time(), 0.0)
mock_datetime.datetime.now.return_value = self.now
self.stopwatch.start()
soon = self.now + datetime.timedelta(seconds=12.345)
mock_datetime.datetime.now.return_value = soon
self.assertEqual(self.stopwatch.elapsed_time(), 12.345)
self.stopwatch._saved = datetime.timedelta(seconds=2)
self.assertEqual(self.stopwatch.elapsed_time(), 14.345)
self.stopwatch.stop()
self.assertEqual(self.stopwatch.elapsed_time(), 14.345)
self.stopwatch.reset()
self.assertEqual(self.stopwatch.elapsed_time(), 0.0)
def test_reset(self, mock_datetime: unittest.mock.Mock):
"""Test resetting the StopWatch."""
mock_datetime.datetime.now.return_value = self.now
self.stopwatch.start()
soon = self.now + datetime.timedelta(seconds=12.345)
mock_datetime.datetime.now.return_value = soon
self.stopwatch.stop()
self.stopwatch.reset()
self.assertIsNone(self.stopwatch._saved)
self.assertIsNone(self.stopwatch._started)
def test_start(self, mock_datetime: unittest.mock.Mock):
"""Test starting the StopWatch."""
self.assertIsNone(self.stopwatch._started)
mock_datetime.datetime.now.return_value = self.now
self.stopwatch.start()
self.assertEqual(self.stopwatch._started, self.now)
def test_stop(self, mock_datetime: unittest.mock.Mock):
"""Test stopping the StopWatch."""
self.assertIsNone(self.stopwatch._saved)
self.stopwatch.stop()
self.assertIsNone(self.stopwatch._saved)
mock_datetime.datetime.now.return_value = self.now
self.stopwatch.start()
delta1 = datetime.timedelta(seconds=12.345)
mock_datetime.datetime.now.return_value = self.now + delta1
self.stopwatch.stop()
self.assertEqual(self.stopwatch._saved, delta1)
self.assertIsNone(self.stopwatch._started)
now = self.now + delta1 + datetime.timedelta(seconds=2)
mock_datetime.datetime.now.return_value = now
self.stopwatch.start()
delta2 = datetime.timedelta(seconds=3)
mock_datetime.datetime.now.return_value = now + delta2
self.stopwatch.stop()
self.assertEqual(self.stopwatch._saved, delta1 + delta2)
self.stopwatch.stop()
self.assertEqual(self.stopwatch._saved, delta1 + delta2)