Add required_keys for configtypes.Dict
This commit is contained in:
parent
bc526cf0ce
commit
2ba637891a
@ -83,10 +83,10 @@ new_instance_open_target_window:
|
||||
|
||||
searchengines:
|
||||
default:
|
||||
# FIXME:conf what if the user deletes/renames DEFAULT?
|
||||
DEFAULT: https://duckduckgo.com/?q={}
|
||||
type:
|
||||
name: Dict
|
||||
required_keys: ['DEFAULT']
|
||||
keytype: String
|
||||
valtype: SearchEngineUrl
|
||||
desc: >-
|
||||
|
@ -1030,7 +1030,8 @@ class Dict(BaseType):
|
||||
|
||||
"""A dictionary of values."""
|
||||
|
||||
def __init__(self, keytype, valtype, *, fixed_keys=None, none_ok=False):
|
||||
def __init__(self, keytype, valtype, *, fixed_keys=None,
|
||||
required_keys=None, none_ok=False):
|
||||
super().__init__(none_ok)
|
||||
# If the keytype is not a string, we'll get problems with showing it as
|
||||
# json in to_str() as json converts keys to strings.
|
||||
@ -1038,12 +1039,17 @@ class Dict(BaseType):
|
||||
self.keytype = keytype
|
||||
self.valtype = valtype
|
||||
self.fixed_keys = fixed_keys
|
||||
self.required_keys = required_keys
|
||||
|
||||
def _validate_keys(self, value):
|
||||
if (self.fixed_keys is not None and
|
||||
value.keys() != set(self.fixed_keys)):
|
||||
raise configexc.ValidationError(
|
||||
value, "Expected keys {}".format(self.fixed_keys))
|
||||
if (self.required_keys is not None and not
|
||||
set(self.required_keys).issubset(value.keys())):
|
||||
raise configexc.ValidationError(
|
||||
value, "Required keys {}".format(self.required_keys))
|
||||
|
||||
def _none_value(self, value=None):
|
||||
"""Return the value to be used when the setting is None.
|
||||
|
@ -73,3 +73,8 @@ def test_partial_compare_not_equal(val1, val2, error):
|
||||
])
|
||||
def test_pattern_match(pattern, value, expected):
|
||||
assert utils.pattern_match(pattern=pattern, value=value) == expected
|
||||
|
||||
|
||||
def test_nop_contextmanager():
|
||||
with utils.nop_contextmanager():
|
||||
pass
|
||||
|
@ -23,6 +23,7 @@
|
||||
import re
|
||||
import pprint
|
||||
import os.path
|
||||
import contextlib
|
||||
|
||||
import pytest
|
||||
|
||||
@ -170,3 +171,8 @@ def abs_datapath():
|
||||
"""Get the absolute path to the end2end data directory."""
|
||||
file_abs = os.path.abspath(os.path.dirname(__file__))
|
||||
return os.path.join(file_abs, '..', 'end2end', 'data')
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def nop_contextmanager():
|
||||
yield
|
||||
|
@ -40,6 +40,7 @@ from PyQt5.QtNetwork import QNetworkProxy
|
||||
from qutebrowser.config import configtypes, configexc
|
||||
from qutebrowser.utils import debug, utils, qtutils
|
||||
from qutebrowser.browser.network import pac
|
||||
from tests.helpers import utils as testutils
|
||||
|
||||
|
||||
class Font(QFont):
|
||||
@ -1390,16 +1391,35 @@ class TestDict:
|
||||
valtype=configtypes.Int())
|
||||
assert typ.from_str('{"answer": 42}') == {"answer": 42}
|
||||
|
||||
@pytest.mark.parametrize('val', [
|
||||
{"one": "1"}, # missing key
|
||||
{"one": "1", "two": "2", "three": "3"}, # extra key
|
||||
@pytest.mark.parametrize('kind, val, ok', [
|
||||
('fixed', {"one": "1"}, False), # missing key
|
||||
('fixed', {"one": "1", "two": "2", "three": "3"}, False), # extra key
|
||||
('fixed', {"one": "1", "two": "2"}, True),
|
||||
|
||||
('required', {"one": "1"}, False), # missing key
|
||||
('required', {"one": "1", "two": "2", "three": "3"}, True), # extra
|
||||
('required', {"one": "1", "two": "2"}, True),
|
||||
])
|
||||
@pytest.mark.parametrize('from_str', [True, False])
|
||||
def test_fixed_keys(self, klass, val, from_str):
|
||||
d = klass(keytype=configtypes.String(), valtype=configtypes.String(),
|
||||
fixed_keys=['one', 'two'])
|
||||
def test_keys(self, klass, kind, val, ok, from_str):
|
||||
if kind == 'fixed':
|
||||
d = klass(keytype=configtypes.String(),
|
||||
valtype=configtypes.String(),
|
||||
fixed_keys=['one', 'two'])
|
||||
message = 'Expected keys .*'
|
||||
elif kind == 'required':
|
||||
d = klass(keytype=configtypes.String(),
|
||||
valtype=configtypes.String(),
|
||||
required_keys=['one', 'two'])
|
||||
message = 'Required keys .*'
|
||||
|
||||
with pytest.raises(configexc.ValidationError):
|
||||
if ok:
|
||||
expectation = testutils.nop_contextmanager()
|
||||
else:
|
||||
expectation = pytest.raises(configexc.ValidationError,
|
||||
match=message)
|
||||
|
||||
with expectation:
|
||||
if from_str:
|
||||
d.from_str(json.dumps(val))
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user