diff --git a/mopidy/utils/config.py b/mopidy/utils/config.py index 2fcdfd94..ab6cb2f7 100644 --- a/mopidy/utils/config.py +++ b/mopidy/utils/config.py @@ -81,3 +81,12 @@ class String(ConfigValue): def serialize(self, value): return value.strip() + + +class Integer(ConfigValue): + def deserialize(self, value): + value = int(value.strip()) + validate_choice(value, self.choices) + validate_minimum(value, self.minimum) + validate_maximum(value, self.maximum) + return value diff --git a/tests/utils/config_test.py b/tests/utils/config_test.py index 5345e5a4..b973cef1 100644 --- a/tests/utils/config_test.py +++ b/tests/utils/config_test.py @@ -109,3 +109,40 @@ class StringTest(unittest.TestCase): def test_format_masks_secrets(self): value = config.String(secret=True) self.assertEqual('********', value.format('s3cret')) + + +class IntegerTest(unittest.TestCase): + def test_deserialize_converts_to_int(self): + value = config.Integer() + self.assertEqual(123, value.deserialize('123')) + self.assertEqual(0, value.deserialize('0')) + self.assertEqual(-10, value.deserialize('-10')) + + def test_deserialize_fails_on_bad_data(self): + value = config.Integer() + with self.assertRaises(ValueError): + value.deserialize('asd') + with self.assertRaises(ValueError): + value.deserialize('3.14') + + def test_deserialize_enforces_choices(self): + value = config.Integer(choices=[1, 2, 3]) + self.assertEqual(3, value.deserialize('3')) + with self.assertRaises(ValueError): + value.deserialize('5') + + def test_deserialize_enforces_minimum(self): + value = config.Integer(minimum=10) + self.assertEqual(15, value.deserialize('15')) + with self.assertRaises(ValueError): + value.deserialize('5') + + def test_deserialize_enforces_maximum(self): + value = config.Integer(maximum=10) + self.assertEqual(5, value.deserialize('5')) + with self.assertRaises(ValueError): + value.deserialize('15') + + def test_format_masks_secrets(self): + value = config.Integer(secret=True) + self.assertEqual('********', value.format('1337'))