parent
0b491f6caf
commit
e5e1a0d95c
@ -48,6 +48,7 @@ Fixed
|
||||
- Fixed crash when downloading a file without any path information (e.g a
|
||||
magnet link).
|
||||
- Fixed crashes when opening an empty URL (e.g. via pasting).
|
||||
- Fixed validation of duplicate values in `hints -> chars`.
|
||||
|
||||
v0.5.1
|
||||
------
|
||||
|
@ -870,7 +870,7 @@ def data(readonly=False):
|
||||
"Mode to use for hints."),
|
||||
|
||||
('chars',
|
||||
SettingValue(typ.String(minlen=2, completions=[
|
||||
SettingValue(typ.UniqueCharString(minlen=2, completions=[
|
||||
('asdfghjkl', "Home row"),
|
||||
('dhtnaoeu', "Home row (Dvorak)"),
|
||||
('abcdefghijklmnopqrstuvwxyz', "All letters"),
|
||||
|
@ -283,6 +283,21 @@ class String(BaseType):
|
||||
return super().complete()
|
||||
|
||||
|
||||
class UniqueCharString(String):
|
||||
|
||||
"""A string which may not contain duplicate chars."""
|
||||
|
||||
def validate(self, value):
|
||||
super().validate(value)
|
||||
if not value:
|
||||
return
|
||||
|
||||
# Check for duplicate values
|
||||
if len(set(value)) != len(value):
|
||||
raise configexc.ValidationError(
|
||||
value, "String contains duplicate values!")
|
||||
|
||||
|
||||
class List(BaseType):
|
||||
|
||||
"""Base class for a (string-)list setting."""
|
||||
|
@ -278,9 +278,9 @@ class TestString:
|
||||
|
||||
"""Test String."""
|
||||
|
||||
@pytest.fixture
|
||||
def klass(self):
|
||||
return configtypes.String
|
||||
@pytest.fixture(params=[configtypes.String, configtypes.UniqueCharString])
|
||||
def klass(self, request):
|
||||
return request.param
|
||||
|
||||
@pytest.mark.parametrize('minlen, maxlen', [(1, None), (None, 1)])
|
||||
def test_lengths_valid(self, klass, minlen, maxlen):
|
||||
@ -297,16 +297,16 @@ class TestString:
|
||||
|
||||
@pytest.mark.parametrize('kwargs, val', [
|
||||
({'none_ok': True}, ''), # Empty with none_ok
|
||||
({}, "Hello World! :-)"),
|
||||
({}, "Test! :-)"),
|
||||
# Forbidden chars
|
||||
({'forbidden': 'xyz'}, 'foobar'),
|
||||
({'forbidden': 'xyz'}, 'fobar'),
|
||||
({'forbidden': 'xyz'}, 'foXbar'),
|
||||
# Lengths
|
||||
({'minlen': 2}, 'fo'),
|
||||
({'minlen': 2, 'maxlen': 3}, 'fo'),
|
||||
({'minlen': 2, 'maxlen': 3}, 'foo'),
|
||||
({'minlen': 2, 'maxlen': 3}, 'abc'),
|
||||
# valid_values
|
||||
({'valid_values': configtypes.ValidValues('fooo')}, 'fooo'),
|
||||
({'valid_values': configtypes.ValidValues('abcd')}, 'abcd'),
|
||||
])
|
||||
def test_validate_valid(self, klass, kwargs, val):
|
||||
klass(**kwargs).validate(val)
|
||||
@ -320,16 +320,21 @@ class TestString:
|
||||
({'minlen': 2}, 'f'),
|
||||
({'maxlen': 2}, 'fob'),
|
||||
({'minlen': 2, 'maxlen': 3}, 'f'),
|
||||
({'minlen': 2, 'maxlen': 3}, 'fooo'),
|
||||
({'minlen': 2, 'maxlen': 3}, 'abcd'),
|
||||
# valid_values
|
||||
({'valid_values': configtypes.ValidValues('blah')}, 'fooo'),
|
||||
({'valid_values': configtypes.ValidValues('blah')}, 'abcd'),
|
||||
])
|
||||
def test_validate_invalid(self, klass, kwargs, val):
|
||||
with pytest.raises(configexc.ValidationError):
|
||||
klass(**kwargs).validate(val)
|
||||
|
||||
def test_validate_duplicate_invalid(self):
|
||||
typ = configtypes.UniqueCharString()
|
||||
with pytest.raises(configexc.ValidationError):
|
||||
typ.validate('foobar')
|
||||
|
||||
def test_transform(self, klass):
|
||||
assert klass().transform('foobar') == 'foobar'
|
||||
assert klass().transform('fobar') == 'fobar'
|
||||
|
||||
@pytest.mark.parametrize('value', [
|
||||
None,
|
||||
|
Loading…
Reference in New Issue
Block a user