Set up tests, add tests for common.util.time, add %d
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Lukáš Kucharczyk 2023-01-05 15:18:57 +01:00
parent 67f5090bf8
commit 34ce1e9b05
Signed by: lukas
SSH Key Fingerprint: SHA256:vMuSwvwAvcT6htVAioMP7rzzwMQNi3roESyhv+nAxeg
6 changed files with 60 additions and 33 deletions

7
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}

View File

@ -1,5 +1,6 @@
## Unreleased ## Unreleased
* Add tests for common.util.time * Add %d for days to common.util.time.format_duration
* Set up tests, add tests for common.util.time
* Display total hours played on homepage * Display total hours played on homepage
* Add format_duration to common.util.time * Add format_duration to common.util.time
* Allow deleting sessions * Allow deleting sessions

View File

@ -39,7 +39,7 @@ createsuperuser:
shell: shell:
python src/web/manage.py shell python src/web/manage.py shell
poetry.lock: poetry.lock: pyproject.toml
poetry install poetry install
test: poetry.lock test: poetry.lock

6
poetry.lock generated
View File

@ -98,14 +98,14 @@ files = [
[[package]] [[package]]
name = "django" name = "django"
version = "4.1.4" version = "4.1.5"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "Django-4.1.4-py3-none-any.whl", hash = "sha256:0b223bfa55511f950ff741983d408d78d772351284c75e9f77d2b830b6b4d148"}, {file = "Django-4.1.5-py3-none-any.whl", hash = "sha256:4b214a05fe4c99476e99e2445c8b978c8369c18d4dea8e22ec412862715ad763"},
{file = "Django-4.1.4.tar.gz", hash = "sha256:d38a4e108d2386cb9637da66a82dc8d0733caede4c83c4afdbda78af4214211b"}, {file = "Django-4.1.5.tar.gz", hash = "sha256:ff56ebd7ead0fd5dbe06fe157b0024a7aaea2e0593bb3785fb594cf94dad58ef"},
] ]
[package.dependencies] [package.dependencies]

View File

@ -13,32 +13,27 @@ def format_duration(
) -> str: ) -> str:
""" """
Format timedelta into the specified format_string. Format timedelta into the specified format_string.
If duration is less than 60 seconds, skips formatting, returns "less than a minute".
If duration is 0, skips formatting, returns 0.
Valid format variables: Valid format variables:
- %H hours - %H hours
- %m minutes - %m minutes
- %s seconds - %s seconds
- %r total seconds
""" """
seconds_in_hours = 3600 minute_seconds = 60
seconds_in_minute = 60 hour_seconds = 60 * minute_seconds
hours: int day_seconds = 24 * hour_seconds
minutes: int seconds_total = int(duration.total_seconds())
seconds: int days, remainder = divmod(seconds_total, day_seconds)
seconds_total: int hours, remainder = divmod(remainder, hour_seconds)
remainder: int minutes, seconds = divmod(remainder, minute_seconds)
seconds_total = duration.total_seconds() literals = {
if seconds_total == 0: "%d": str(days),
return 0 "%H": str(hours),
else: "%m": str(minutes),
hours = int(seconds_total // seconds_in_hours) "%s": str(seconds),
remainder = int(seconds_total % seconds_in_hours) "%r": str(seconds_total),
minutes = int(remainder // seconds_in_minute) }
if hours == 0 and minutes == 0: formatted_string = format_string
return "less than a minute" for pattern, replacement in literals.items():
seconds = int(minutes % seconds_in_minute) formatted_string = re.sub(pattern, replacement, formatted_string)
literals = {"%H": str(hours), "%m": str(minutes), "%s": str(seconds)} return formatted_string
formatted_string = format_string
for pattern, replacement in literals.items():
formatted_string = re.sub(pattern, replacement, formatted_string)
return formatted_string

View File

@ -8,6 +8,11 @@ class FormatDurationTest(unittest.TestCase):
return super().setUp() return super().setUp()
def test_only_days(self):
delta = timedelta(days=3)
result = format_duration(delta, "%d days")
self.assertEqual(result, "3 days")
def test_only_hours(self): def test_only_hours(self):
delta = timedelta(hours=1) delta = timedelta(hours=1)
result = format_duration(delta, "%H hours") result = format_duration(delta, "%H hours")
@ -23,7 +28,26 @@ class FormatDurationTest(unittest.TestCase):
result = format_duration(delta, "%s seconds") result = format_duration(delta, "%s seconds")
self.assertEqual(result, "1 seconds") self.assertEqual(result, "1 seconds")
def test_only_less_than_minute_seconds(self): def test_only_rawseconds(self):
delta = timedelta(seconds=59) delta = timedelta(seconds=5690)
result = format_duration(delta) result = format_duration(delta, "%r total seconds")
self.assertEqual(result, "less than a minute") self.assertEqual(result, "5690 total seconds")
def test_empty(self):
delta = timedelta()
result = format_duration(delta, "")
self.assertEqual(result, "")
def test_zero(self):
delta = timedelta()
result = format_duration(delta, "%r seconds")
self.assertEqual(result, "0 seconds")
def test_all_at_once(self):
delta = timedelta(days=50, hours=10, minutes=34, seconds=24)
result = format_duration(
delta, "%d days, %H hours, %m minutes, %s seconds, %r total seconds"
)
self.assertEqual(
result, "50 days, 10 hours, 34 minutes, 24 seconds, 4358064 total seconds"
)