Merge pull request #1967 from Henddher/unit_tests
Tests for evennia/utils/validatorfuncs.
This commit is contained in:
commit
8ee9eb5eef
2 changed files with 167 additions and 16 deletions
151
evennia/utils/tests/test_validatorfuncs.py
Normal file
151
evennia/utils/tests/test_validatorfuncs.py
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
"""Tests for validatorfuncs """
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from evennia.utils import validatorfuncs
|
||||||
|
import mock
|
||||||
|
import datetime
|
||||||
|
import pytz
|
||||||
|
|
||||||
|
|
||||||
|
class TestValidatorFuncs(TestCase):
|
||||||
|
|
||||||
|
def test_text_ok(self):
|
||||||
|
for val in [None, -123, 'abc', 1.234, {1:True, 2:False}, ['a', 1]]:
|
||||||
|
self.assertEqual(str(val), validatorfuncs.text(val))
|
||||||
|
|
||||||
|
@mock.patch('builtins.str')
|
||||||
|
def test_text_raises_ValueError(self, mocked_str):
|
||||||
|
mocked_str.side_effect = Exception
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.text(None)
|
||||||
|
|
||||||
|
def test_color_ok(self):
|
||||||
|
for color in ['r', 'g', 'b', 'H', 'R', 'M', '^']:
|
||||||
|
self.assertEqual(color, validatorfuncs.color(color))
|
||||||
|
|
||||||
|
def test_color_falsy_raises_ValueError(self):
|
||||||
|
for color in [None, (), [], False, True, {}]:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.color(color)
|
||||||
|
|
||||||
|
def test_datetime_ok(self):
|
||||||
|
for dt in ['Oct 12 1:00 1492', 'Jan 2 12:00 2020', 'Dec 31 00:00 2018']:
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(validatorfuncs.datetime(dt, from_tz=pytz.UTC),
|
||||||
|
datetime.datetime))
|
||||||
|
|
||||||
|
def test_datetime_raises_ValueError(self):
|
||||||
|
for dt in ['', 'January 1, 2019', '1/1/2019', 'Jan 1 2019']:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.datetime(dt)
|
||||||
|
|
||||||
|
def test_duration_ok(self):
|
||||||
|
for d in ['1d', '2w', '3h', '4s', '5m', '6y']:
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(validatorfuncs.duration(d), datetime.timedelta))
|
||||||
|
|
||||||
|
# THE FOLLOWING FAILS, year calculation seems to be incorrect
|
||||||
|
# self.assertEqual(
|
||||||
|
# datetime.timedelta(1+5*365, 2, 0, 0, 3, 4, 5),
|
||||||
|
# validatorfuncs.duration('1d 2s 3m 4h 5w 5y'))
|
||||||
|
|
||||||
|
def test_duration_raises_ValueError(self):
|
||||||
|
for d in ['', '1', '5days', '1Week']:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.duration(d)
|
||||||
|
|
||||||
|
def test_future_ok(self):
|
||||||
|
year = int(datetime.datetime.utcnow().strftime("%Y"))
|
||||||
|
for f in [f'Jan 2 12:00 {year+1}', f'Dec 31 00:00 {year+1}']:
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(validatorfuncs.future(f, from_tz=pytz.UTC),
|
||||||
|
datetime.datetime))
|
||||||
|
|
||||||
|
def test_future_raises_ValueError(self):
|
||||||
|
year = int(datetime.datetime.utcnow().strftime("%Y"))
|
||||||
|
for f in [f'Jan 2 12:00 {year-1}', f'Dec 31 00:00 {year-1}']:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.future(f, from_tz=pytz.UTC)
|
||||||
|
|
||||||
|
def test_signed_integer_ok(self):
|
||||||
|
for si in ['123', '4567890', '001', '-123', '-45', '0']:
|
||||||
|
self.assertEqual(int(si), validatorfuncs.signed_integer(si))
|
||||||
|
|
||||||
|
@mock.patch('builtins.int')
|
||||||
|
def test_signed_integer_raises_ValueError(self, mocked_int):
|
||||||
|
for si in ['', '000', 'abc']:
|
||||||
|
mocked_int.side_effect = ValueError
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.signed_integer(si)
|
||||||
|
|
||||||
|
def test_positive_integer_ok(self):
|
||||||
|
for pi in ['123', '4567890', '001']:
|
||||||
|
self.assertEqual(int(pi), validatorfuncs.positive_integer(pi))
|
||||||
|
|
||||||
|
@mock.patch('builtins.int')
|
||||||
|
def test_positive_integer_raises_ValueError(self, mocked_int):
|
||||||
|
mocked_int.return_value = -1
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.positive_integer(str(-1))
|
||||||
|
for pi in ['', '000', 'abc', '-1']:
|
||||||
|
mocked_int.side_effect = ValueError
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.positive_integer(pi)
|
||||||
|
|
||||||
|
def test_unsigned_integer_ok(self):
|
||||||
|
for ui in ['123', '4567890', '001', '0']:
|
||||||
|
self.assertEqual(int(ui), validatorfuncs.unsigned_integer(ui))
|
||||||
|
|
||||||
|
@mock.patch('builtins.int')
|
||||||
|
def test_unsigned_integer_raises_ValueError(self, mocked_int):
|
||||||
|
mocked_int.return_value = -1
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.unsigned_integer(str(-1))
|
||||||
|
for ui in ['', '000', 'abc', '-1', '0']:
|
||||||
|
mocked_int.side_effect = ValueError
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.unsigned_integer(ui)
|
||||||
|
|
||||||
|
def test_boolean(self):
|
||||||
|
for b in ['true', '1', 'on', 'ENABLED']:
|
||||||
|
self.assertTrue(validatorfuncs.boolean(b))
|
||||||
|
for b in ['FalSe', '0', 'oFF', 'disabled']:
|
||||||
|
self.assertFalse(validatorfuncs.boolean(b))
|
||||||
|
|
||||||
|
def test_boolean_raises_ValueError(self):
|
||||||
|
for b in ['', None, 1, 0, True, False, [None], {True:True}]:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.boolean(b)
|
||||||
|
|
||||||
|
def test_timezone_ok(self):
|
||||||
|
for tz in ['America/Chicago', 'GMT', 'UTC']:
|
||||||
|
self.assertEqual(tz, validatorfuncs.timezone(tz).zone)
|
||||||
|
|
||||||
|
def test_timezone_raises_ValueError(self):
|
||||||
|
for tz in ['America', None, '', 'Mars', 'DT']:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.timezone(tz)
|
||||||
|
|
||||||
|
def test_email_ok(self):
|
||||||
|
for e in ['a@a.aa', 'zeus@olympus.net']:
|
||||||
|
self.assertEqual(e, validatorfuncs.email(e))
|
||||||
|
|
||||||
|
def test_email_raises_ValueError(self):
|
||||||
|
for e in ['', None, ['abc@abc.com'], 123]:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.email(e)
|
||||||
|
|
||||||
|
def test_lock_ok(self):
|
||||||
|
for l in ['do:true;look:no', 'a:t']:
|
||||||
|
self.assertEqual(l, validatorfuncs.lock(l))
|
||||||
|
|
||||||
|
def test_lock_raises_ValueError(self):
|
||||||
|
for l in [';;;', '', ':', ':::', ';:;:', 'x:', ':y']:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.lock(l)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.lock('view:',
|
||||||
|
access_options=())
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validatorfuncs.lock('view:',
|
||||||
|
access_options=('look'))
|
||||||
|
|
@ -68,13 +68,13 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs)
|
||||||
entry = f"{split_time[0]} {split_time[1]} {split_time[2]} {split_time[3]}"
|
entry = f"{split_time[0]} {split_time[1]} {split_time[2]} {split_time[3]}"
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"{option_key} must be entered in a 24-hour format such as: {now.strftime('%b %d %H:%H')}"
|
f"{option_key} must be entered in a 24-hour format such as: {now.strftime('%b %d %H:%M')}"
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
local = _dt.datetime.strptime(input, "%b %d %H:%M %Y")
|
local = _dt.datetime.strptime(entry, "%b %d %H:%M %Y")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"{option_key} must be entered in a 24-hour format such as: {now.strftime('%b %d %H:%H')}"
|
f"{option_key} must be entered in a 24-hour format such as: {now.strftime('%b %d %H:%M')}"
|
||||||
)
|
)
|
||||||
local_tz = from_tz.localize(local)
|
local_tz = from_tz.localize(local)
|
||||||
return local_tz.astimezone(utc)
|
return local_tz.astimezone(utc)
|
||||||
|
|
@ -93,7 +93,7 @@ def duration(entry, option_key="Duration", **kwargs):
|
||||||
timedelta
|
timedelta
|
||||||
|
|
||||||
"""
|
"""
|
||||||
time_string = entry.split(" ")
|
time_string = entry.lower().split(" ")
|
||||||
seconds = 0
|
seconds = 0
|
||||||
minutes = 0
|
minutes = 0
|
||||||
hours = 0
|
hours = 0
|
||||||
|
|
@ -101,18 +101,18 @@ def duration(entry, option_key="Duration", **kwargs):
|
||||||
weeks = 0
|
weeks = 0
|
||||||
|
|
||||||
for interval in time_string:
|
for interval in time_string:
|
||||||
if _re.match(r"^[\d]+s$", interval.lower()):
|
if _re.match(r"^[\d]+s$", interval):
|
||||||
seconds = +int(interval.lower().rstrip("s"))
|
seconds = +int(interval.rstrip("s"))
|
||||||
elif _re.match(r"^[\d]+m$", interval):
|
elif _re.match(r"^[\d]+m$", interval):
|
||||||
minutes = +int(interval.lower().rstrip("m"))
|
minutes = +int(interval.rstrip("m"))
|
||||||
elif _re.match(r"^[\d]+h$", interval):
|
elif _re.match(r"^[\d]+h$", interval):
|
||||||
hours = +int(interval.lower().rstrip("h"))
|
hours = +int(interval.rstrip("h"))
|
||||||
elif _re.match(r"^[\d]+d$", interval):
|
elif _re.match(r"^[\d]+d$", interval):
|
||||||
days = +int(interval.lower().rstrip("d"))
|
days = +int(interval.rstrip("d"))
|
||||||
elif _re.match(r"^[\d]+w$", interval):
|
elif _re.match(r"^[\d]+w$", interval):
|
||||||
weeks = +int(interval.lower().rstrip("w"))
|
weeks = +int(interval.rstrip("w"))
|
||||||
elif _re.match(r"^[\d]+y$", interval):
|
elif _re.match(r"^[\d]+y$", interval):
|
||||||
days = +int(interval.lower().rstrip("y")) * 365
|
days = +int(interval.rstrip("y")) * 365
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Could not convert section '{interval}' to a {option_key}.")
|
raise ValueError(f"Could not convert section '{interval}' to a {option_key}.")
|
||||||
|
|
||||||
|
|
@ -120,8 +120,8 @@ def duration(entry, option_key="Duration", **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def future(entry, option_key="Future Datetime", from_tz=None, **kwargs):
|
def future(entry, option_key="Future Datetime", from_tz=None, **kwargs):
|
||||||
time = datetime(entry, option_key)
|
time = datetime(entry, option_key, from_tz=from_tz)
|
||||||
if time < _dt.datetime.utcnow():
|
if time < _dt.datetime.utcnow().replace(tzinfo=_dt.timezone.utc):
|
||||||
raise ValueError(f"That {option_key} is in the past! Must give a Future datetime!")
|
raise ValueError(f"That {option_key} is in the past! Must give a Future datetime!")
|
||||||
return time
|
return time
|
||||||
|
|
||||||
|
|
@ -160,10 +160,10 @@ def boolean(entry, option_key="True/False", **kwargs):
|
||||||
Returns:
|
Returns:
|
||||||
Boolean
|
Boolean
|
||||||
"""
|
"""
|
||||||
entry = entry.upper()
|
|
||||||
error = f"Must enter 0 (false) or 1 (true) for {option_key}. Also accepts True, False, On, Off, Yes, No, Enabled, and Disabled"
|
error = f"Must enter 0 (false) or 1 (true) for {option_key}. Also accepts True, False, On, Off, Yes, No, Enabled, and Disabled"
|
||||||
if not entry:
|
if not isinstance(entry, str):
|
||||||
raise ValueError(error)
|
raise ValueError(error)
|
||||||
|
entry = entry.upper()
|
||||||
if entry in ("1", "TRUE", "ON", "ENABLED", "ENABLE", "YES"):
|
if entry in ("1", "TRUE", "ON", "ENABLED", "ENABLE", "YES"):
|
||||||
return True
|
return True
|
||||||
if entry in ("0", "FALSE", "OFF", "DISABLED", "DISABLE", "NO"):
|
if entry in ("0", "FALSE", "OFF", "DISABLED", "DISABLE", "NO"):
|
||||||
|
|
@ -198,7 +198,7 @@ def email(entry, option_key="Email Address", **kwargs):
|
||||||
if not entry:
|
if not entry:
|
||||||
raise ValueError("Email address field empty!")
|
raise ValueError("Email address field empty!")
|
||||||
try:
|
try:
|
||||||
_val_email(entry) # offloading the hard work to Django!
|
_val_email(str(entry)) # offloading the hard work to Django!
|
||||||
except _error:
|
except _error:
|
||||||
raise ValueError(f"That isn't a valid {option_key}!")
|
raise ValueError(f"That isn't a valid {option_key}!")
|
||||||
return entry
|
return entry
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue