aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_converters.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_converters.py')
-rw-r--r--tests/test_converters.py123
1 files changed, 108 insertions, 15 deletions
diff --git a/tests/test_converters.py b/tests/test_converters.py
index 3cf774c80..35fc5d88e 100644
--- a/tests/test_converters.py
+++ b/tests/test_converters.py
@@ -1,12 +1,13 @@
import asyncio
-from datetime import datetime
-from unittest.mock import MagicMock
+import datetime
+from unittest.mock import MagicMock, patch
import pytest
+from dateutil.relativedelta import relativedelta
from discord.ext.commands import BadArgument
from bot.converters import (
- ExpirationDate,
+ Duration,
TagContentConverter,
TagNameConverter,
ValidPythonIdentifier,
@@ -16,18 +17,6 @@ from bot.converters import (
@pytest.mark.parametrize(
('value', 'expected'),
(
- # sorry aliens
- ('2199-01-01T00:00:00', datetime(2199, 1, 1)),
- )
-)
-def test_expiration_date_converter_for_valid(value: str, expected: datetime):
- converter = ExpirationDate()
- assert asyncio.run(converter.convert(None, value)) == expected
-
-
- ('value', 'expected'),
- (
('hello', 'hello'),
(' h ello ', 'h ello')
)
@@ -91,3 +80,107 @@ def test_valid_python_identifier_for_valid(value: str):
def test_valid_python_identifier_for_invalid(value: str):
with pytest.raises(BadArgument, match=f'`{value}` is not a valid Python identifier'):
asyncio.run(ValidPythonIdentifier.convert(None, value))
+
+
+FIXED_UTC_NOW = datetime.datetime.fromisoformat('2019-01-01T00:00:00')
+
+
+ params=(
+ # Simple duration strings
+ ('1Y', {"years": 1}),
+ ('1y', {"years": 1}),
+ ('1year', {"years": 1}),
+ ('1years', {"years": 1}),
+ ('1m', {"months": 1}),
+ ('1month', {"months": 1}),
+ ('1months', {"months": 1}),
+ ('1w', {"weeks": 1}),
+ ('1W', {"weeks": 1}),
+ ('1week', {"weeks": 1}),
+ ('1weeks', {"weeks": 1}),
+ ('1d', {"days": 1}),
+ ('1D', {"days": 1}),
+ ('1day', {"days": 1}),
+ ('1days', {"days": 1}),
+ ('1h', {"hours": 1}),
+ ('1H', {"hours": 1}),
+ ('1hour', {"hours": 1}),
+ ('1hours', {"hours": 1}),
+ ('1M', {"minutes": 1}),
+ ('1minute', {"minutes": 1}),
+ ('1minutes', {"minutes": 1}),
+ ('1s', {"seconds": 1}),
+ ('1S', {"seconds": 1}),
+ ('1second', {"seconds": 1}),
+ ('1seconds', {"seconds": 1}),
+
+ # Complex duration strings
+ (
+ '1y1m1w1d1H1M1S',
+ {
+ "years": 1,
+ "months": 1,
+ "weeks": 1,
+ "days": 1,
+ "hours": 1,
+ "minutes": 1,
+ "seconds": 1
+ }
+ ),
+ ('5y100S', {"years": 5, "seconds": 100}),
+ ('2w28H', {"weeks": 2, "hours": 28}),
+
+ # Duration strings with spaces
+ ('1 year 2 months', {"years": 1, "months": 2}),
+ ('1d 2H', {"days": 1, "hours": 2}),
+ ('1 week2 days', {"weeks": 1, "days": 2}),
+ )
+)
+def create_future_datetime(request):
+ """Yields duration string and target datetime.datetime object."""
+ duration, duration_dict = request.param
+ future_datetime = FIXED_UTC_NOW + relativedelta(**duration_dict)
+ yield duration, future_datetime
+
+
+def test_duration_converter_for_valid(create_future_datetime: tuple):
+ converter = Duration()
+ duration, expected = create_future_datetime
+ with patch('bot.converters.datetime') as mock_datetime:
+ mock_datetime.utcnow.return_value = FIXED_UTC_NOW
+ assert asyncio.run(converter.convert(None, duration)) == expected
+
+
+ ('duration'),
+ (
+ # Units in wrong order
+ ('1d1w'),
+ ('1s1y'),
+
+ # Duplicated units
+ ('1 year 2 years'),
+ ('1 M 10 minutes'),
+
+ # Unknown substrings
+ ('1MVes'),
+ ('1y3breads'),
+
+ # Missing amount
+ ('ym'),
+
+ # Incorrect whitespace
+ (" 1y"),
+ ("1S "),
+ ("1y 1m"),
+
+ # Garbage
+ ('Guido van Rossum'),
+ ('lemon lemon lemon lemon lemon lemon lemon'),
+ )
+)
+def test_duration_converter_for_invalid(duration: str):
+ converter = Duration()
+ with pytest.raises(BadArgument, match=f'`{duration}` is not a valid duration string.'):
+ asyncio.run(converter.convert(None, duration))