Add basic pattern support for config.py
This commit is contained in:
parent
a3dfec20c1
commit
3ade923edb
@ -33,7 +33,7 @@ from PyQt5.QtCore import pyqtSignal, QObject, QSettings
|
|||||||
|
|
||||||
import qutebrowser
|
import qutebrowser
|
||||||
from qutebrowser.config import configexc, config, configdata, configutils
|
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
|
# The StateConfig instance
|
||||||
@ -308,6 +308,9 @@ class ConfigAPI:
|
|||||||
except configexc.Error as e:
|
except configexc.Error as e:
|
||||||
text = "While {} '{}'".format(action, name)
|
text = "While {} '{}'".format(action, name)
|
||||||
self.errors.append(configexc.ConfigErrorDesc(text, e))
|
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):
|
def finalize(self):
|
||||||
"""Do work which needs to be done after reading config.py."""
|
"""Do work which needs to be done after reading config.py."""
|
||||||
@ -317,13 +320,15 @@ class ConfigAPI:
|
|||||||
with self._handle_error('reading', 'autoconfig.yml'):
|
with self._handle_error('reading', 'autoconfig.yml'):
|
||||||
read_autoconfig()
|
read_autoconfig()
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name, pattern=None):
|
||||||
with self._handle_error('getting', name):
|
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):
|
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'):
|
def bind(self, key, command, mode='normal'):
|
||||||
with self._handle_error('binding', key):
|
with self._handle_error('binding', key):
|
||||||
@ -401,8 +406,7 @@ class ConfigPyWriter:
|
|||||||
|
|
||||||
def _gen_options(self):
|
def _gen_options(self):
|
||||||
"""Generate the options part of the config."""
|
"""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']:
|
if opt.name in ['bindings.commands', 'bindings.default']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -421,7 +425,11 @@ class ConfigPyWriter:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
yield self._line("# - {}".format(val))
|
yield self._line("# - {}".format(val))
|
||||||
|
|
||||||
|
if pattern is None:
|
||||||
yield self._line('c.{} = {!r}'.format(opt.name, value))
|
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 ''
|
yield ''
|
||||||
|
|
||||||
def _gen_bindings(self):
|
def _gen_bindings(self):
|
||||||
|
@ -28,7 +28,7 @@ from PyQt5.QtCore import QSettings
|
|||||||
|
|
||||||
from qutebrowser.config import (config, configfiles, configexc, configdata,
|
from qutebrowser.config import (config, configfiles, configexc, configdata,
|
||||||
configtypes)
|
configtypes)
|
||||||
from qutebrowser.utils import utils, usertypes
|
from qutebrowser.utils import utils, usertypes, urlmatch
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
@ -500,16 +500,29 @@ class TestConfigPy:
|
|||||||
@pytest.mark.parametrize('line', [
|
@pytest.mark.parametrize('line', [
|
||||||
'c.colors.hints.bg = "red"',
|
'c.colors.hints.bg = "red"',
|
||||||
'config.set("colors.hints.bg", "red")',
|
'config.set("colors.hints.bg", "red")',
|
||||||
|
'config.set("colors.hints.bg", "red", pattern=None)',
|
||||||
])
|
])
|
||||||
def test_set(self, confpy, line):
|
def test_set(self, confpy, line):
|
||||||
confpy.write(line)
|
confpy.write(line)
|
||||||
confpy.read()
|
confpy.read()
|
||||||
assert config.instance.get_obj('colors.hints.bg') == 'red'
|
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('set_first', [True, False])
|
||||||
@pytest.mark.parametrize('get_line', [
|
@pytest.mark.parametrize('get_line', [
|
||||||
'c.colors.hints.fg',
|
'c.colors.hints.fg',
|
||||||
'config.get("colors.hints.fg")',
|
'config.get("colors.hints.fg")',
|
||||||
|
'config.get("colors.hints.fg", pattern=None)',
|
||||||
])
|
])
|
||||||
def test_get(self, confpy, set_first, get_line):
|
def test_get(self, confpy, set_first, get_line):
|
||||||
"""Test whether getting options works correctly."""
|
"""Test whether getting options works correctly."""
|
||||||
@ -523,6 +536,24 @@ class TestConfigPy:
|
|||||||
confpy.write('assert {} == "green"'.format(get_line))
|
confpy.write('assert {} == "green"'.format(get_line))
|
||||||
confpy.read()
|
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', [
|
@pytest.mark.parametrize('line, mode', [
|
||||||
('config.bind(",a", "message-info foo")', 'normal'),
|
('config.bind(",a", "message-info foo")', 'normal'),
|
||||||
('config.bind(",a", "message-info foo", "prompt")', 'prompt'),
|
('config.bind(",a", "message-info foo", "prompt")', 'prompt'),
|
||||||
@ -672,6 +703,21 @@ class TestConfigPy:
|
|||||||
"'qt.args')")
|
"'qt.args')")
|
||||||
assert str(error.exception) == expected
|
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):
|
def test_multiple_errors(self, confpy):
|
||||||
confpy.write("c.foo = 42", "config.set('foo', 42)", "1/0")
|
confpy.write("c.foo = 42", "config.set('foo', 42)", "1/0")
|
||||||
|
|
||||||
@ -862,6 +908,20 @@ class TestConfigPyWriter:
|
|||||||
""").lstrip()
|
""").lstrip()
|
||||||
assert text == expected
|
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):
|
def test_write(self, tmpdir):
|
||||||
pyfile = tmpdir / 'config.py'
|
pyfile = tmpdir / 'config.py'
|
||||||
writer = configfiles.ConfigPyWriter(options=[], bindings={},
|
writer = configfiles.ConfigPyWriter(options=[], bindings={},
|
||||||
|
Loading…
Reference in New Issue
Block a user