configtypes: Add a MappingType base class.

This commit is contained in:
Florian Bruhin 2015-07-23 23:53:00 +02:00
parent 0b1704d829
commit e145d73852
2 changed files with 89 additions and 29 deletions

View File

@ -160,6 +160,31 @@ class BaseType:
return out
class MappingType(BaseType):
"""Base class for any setting which has a mapping to the given values.
Attributes:
MAPPING: The mapping to use.
"""
MAPPING = {}
def __init__(self, none_ok=False):
super().__init__(none_ok)
if list(sorted(self.MAPPING)) != list(sorted(self.valid_values)):
raise ValueError("Mapping {!r} doesn't match valid values "
"{!r}".format(self.MAPPING, self.valid_values))
def validate(self, value):
super().validate(value.lower())
def transform(self, value):
if not value:
return None
return self.MAPPING[value.lower()]
class String(BaseType):
"""Base class for a string setting (case-insensitive).
@ -557,7 +582,7 @@ class Command(BaseType):
return out
class ColorSystem(BaseType):
class ColorSystem(MappingType):
"""Color systems for interpolation."""
@ -565,19 +590,11 @@ class ColorSystem(BaseType):
('hsv', "Interpolate in the HSV color system."),
('hsl', "Interpolate in the HSL color system."))
def validate(self, value):
super().validate(value.lower())
def transform(self, value):
if not value:
return None
else:
mapping = {
'rgb': QColor.Rgb,
'hsv': QColor.Hsv,
'hsl': QColor.Hsl,
}
return mapping[value.lower()]
MAPPING = {
'rgb': QColor.Rgb,
'hsv': QColor.Hsv,
'hsl': QColor.Hsl,
}
class QtColor(BaseType):
@ -1265,7 +1282,7 @@ class AutoSearch(BaseType):
return False
class Position(BaseType):
class Position(MappingType):
"""The position of the tab bar."""
@ -1278,14 +1295,6 @@ class Position(BaseType):
'east': QTabWidget.East,
}
def validate(self, value):
super().validate(value.lower())
def transform(self, value):
if not value:
return None
return self.MAPPING[value.lower()]
class VerticalPosition(BaseType):
@ -1340,7 +1349,7 @@ class SessionName(BaseType):
raise configexc.ValidationError(value, "may not start with '_'!")
class SelectOnRemove(BaseType):
class SelectOnRemove(MappingType):
"""Which tab to select when the focused tab is removed."""
@ -1355,11 +1364,6 @@ class SelectOnRemove(BaseType):
'previous': QTabBar.SelectPreviousTab,
}
def transform(self, value):
if not value:
return None
return self.MAPPING[value]
class LastClose(BaseType):

View File

@ -184,6 +184,62 @@ class TestBaseType:
assert basetype.complete() == completions
class GoodMappingSubclass(configtypes.MappingType):
"""A MappingType we use in TestMappingType which is valid/good."""
valid_values = configtypes.ValidValues('one', 'two')
MAPPING = {
'one': 1,
'two': 2,
}
class BadMappingSubclass(configtypes.MappingType):
"""A MappingType which is missing a value in MAPPING."""
valid_values = configtypes.ValidValues('one', 'two')
MAPPING = {
'one': 1,
}
class TestMappingType:
"""Test MappingType."""
TESTS = {
'': None,
'one': 1,
'two': 2,
'ONE': 1,
}
@pytest.fixture
def klass(self):
return GoodMappingSubclass
@pytest.mark.parametrize('val', TESTS.keys())
def test_validate_valid(self, klass, val):
klass(none_ok=True).validate(val)
@pytest.mark.parametrize('val', ['', 'one!', 'blah'])
def test_validate_invalid(self, klass, val):
with pytest.raises(configexc.ValidationError):
klass().validate(val)
@pytest.mark.parametrize('val, expected', TESTS.items())
def test_transform(self, klass, val, expected):
assert klass().transform(val) == expected
def test_bad_subclass_init(self):
with pytest.raises(ValueError):
BadMappingSubclass()
class TestString:
"""Test String."""