Add basic pattern support for config.py

This commit is contained in:
Florian Bruhin 2018-02-20 18:43:42 +01:00
parent a3dfec20c1
commit 3ade923edb
2 changed files with 77 additions and 9 deletions

View File

@ -33,7 +33,7 @@ from PyQt5.QtCore import pyqtSignal, QObject, QSettings
import qutebrowser
from qutebrowser.config import configexc, config, configdata, configutils
from qutebrowser.utils import standarddir, utils, qtutils, log
from qutebrowser.utils import standarddir, utils, qtutils, log, urlmatch
# The StateConfig instance
@ -308,6 +308,9 @@ class ConfigAPI:
except configexc.Error as e:
text = "While {} '{}'".format(action, name)
self.errors.append(configexc.ConfigErrorDesc(text, e))
except urlmatch.ParseError as e:
text = "While {} '{}' and parsing pattern".format(action, name)
self.errors.append(configexc.ConfigErrorDesc(text, e))
def finalize(self):
"""Do work which needs to be done after reading config.py."""
@ -317,13 +320,15 @@ class ConfigAPI:
with self._handle_error('reading', 'autoconfig.yml'):
read_autoconfig()
def get(self, name):
def get(self, name, pattern=None):
with self._handle_error('getting', name):
return self._config.get_mutable_obj(name)
urlpattern = urlmatch.UrlPattern(pattern) if pattern else None
return self._config.get_mutable_obj(name, pattern=urlpattern)
def set(self, name, value):
def set(self, name, value, pattern=None):
with self._handle_error('setting', name):
self._config.set_obj(name, value)
urlpattern = urlmatch.UrlPattern(pattern) if pattern else None
self._config.set_obj(name, value, pattern=urlpattern)
def bind(self, key, command, mode='normal'):
with self._handle_error('binding', key):
@ -401,8 +406,7 @@ class ConfigPyWriter:
def _gen_options(self):
"""Generate the options part of the config."""
# FIXME:conf handle _pattern
for _pattern, opt, value in self._options:
for pattern, opt, value in self._options:
if opt.name in ['bindings.commands', 'bindings.default']:
continue
@ -421,7 +425,11 @@ class ConfigPyWriter:
except KeyError:
yield self._line("# - {}".format(val))
yield self._line('c.{} = {!r}'.format(opt.name, value))
if pattern is None:
yield self._line('c.{} = {!r}'.format(opt.name, value))
else:
yield self._line('config.set({!r}, {!r}, {!r})'.format(
opt.name, value, str(pattern)))
yield ''
def _gen_bindings(self):

View File

@ -28,7 +28,7 @@ from PyQt5.QtCore import QSettings
from qutebrowser.config import (config, configfiles, configexc, configdata,
configtypes)
from qutebrowser.utils import utils, usertypes
from qutebrowser.utils import utils, usertypes, urlmatch
@pytest.fixture(autouse=True)
@ -500,16 +500,29 @@ class TestConfigPy:
@pytest.mark.parametrize('line', [
'c.colors.hints.bg = "red"',
'config.set("colors.hints.bg", "red")',
'config.set("colors.hints.bg", "red", pattern=None)',
])
def test_set(self, confpy, line):
confpy.write(line)
confpy.read()
assert config.instance.get_obj('colors.hints.bg') == 'red'
def test_set_with_pattern(self, confpy):
option = 'content.javascript.enabled'
pattern = 'https://www.example.com/'
confpy.write('config.set({!r}, False, {!r})'.format(option, pattern))
confpy.read()
assert config.instance.get_obj(option)
assert not config.instance.get_obj_for_pattern(
option, pattern=urlmatch.UrlPattern(pattern))
@pytest.mark.parametrize('set_first', [True, False])
@pytest.mark.parametrize('get_line', [
'c.colors.hints.fg',
'config.get("colors.hints.fg")',
'config.get("colors.hints.fg", pattern=None)',
])
def test_get(self, confpy, set_first, get_line):
"""Test whether getting options works correctly."""
@ -523,6 +536,24 @@ class TestConfigPy:
confpy.write('assert {} == "green"'.format(get_line))
confpy.read()
def test_get_with_pattern(self, confpy):
"""Test whether we get a matching value with a pattern."""
option = 'content.javascript.enabled'
pattern = 'https://www.example.com/'
config.instance.set_obj(option, False,
pattern=urlmatch.UrlPattern(pattern))
confpy.write('assert config.get({!r})'.format(option),
'assert not config.get({!r}, pattern={!r})'
.format(option, pattern))
confpy.read()
def test_get_with_pattern_no_match(self, confpy):
confpy.write(
'val = config.get("content.images", "https://www.example.com")',
'assert val is True',
)
confpy.read()
@pytest.mark.parametrize('line, mode', [
('config.bind(",a", "message-info foo")', 'normal'),
('config.bind(",a", "message-info foo", "prompt")', 'prompt'),
@ -672,6 +703,21 @@ class TestConfigPy:
"'qt.args')")
assert str(error.exception) == expected
@pytest.mark.parametrize('line, action', [
('config.get("content.images", "://")', 'getting'),
('config.set("content.images", False, "://")', 'setting'),
])
def test_invalid_pattern(self, confpy, line, action):
confpy.write(line)
error = confpy.read(error=True)
assert error.text == ("While {} 'content.images' and parsing pattern"
.format(action))
assert isinstance(error.exception, urlmatch.ParseError)
assert str(error.exception) == "No scheme given"
assert error.traceback is None
def test_multiple_errors(self, confpy):
confpy.write("c.foo = 42", "config.set('foo', 42)", "1/0")
@ -862,6 +908,20 @@ class TestConfigPyWriter:
""").lstrip()
assert text == expected
def test_pattern(self):
opt = configdata.Option(
name='opt', typ=configtypes.BoolAsk(), default='ask',
backends=[usertypes.Backend.QtWebEngine], raw_backends=None,
description='Hello World')
options = [
(urlmatch.UrlPattern('https://www.example.com/'), opt, 'ask'),
]
writer = configfiles.ConfigPyWriter(options=options, bindings={},
commented=False)
text = '\n'.join(writer._gen_lines())
expected = "config.set('opt', 'ask', 'https://www.example.com/')"
assert expected in text
def test_write(self, tmpdir):
pyfile = tmpdir / 'config.py'
writer = configfiles.ConfigPyWriter(options=[], bindings={},