1# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
2# Copyright 2015-2021 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
3
4# This file is part of qutebrowser.
5#
6# qutebrowser is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# qutebrowser is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with qutebrowser.  If not, see <https://www.gnu.org/licenses/>.
18
19"""Tests for qutebrowser.config.configexc."""
20
21import textwrap
22
23import pytest
24
25from qutebrowser.config import configexc
26from qutebrowser.utils import usertypes
27
28
29def test_validation_error():
30    e = configexc.ValidationError('val', 'msg')
31    assert e.option is None
32    assert str(e) == "Invalid value 'val' - msg"
33
34
35@pytest.mark.parametrize('deleted, renamed, expected', [
36    (False, None, "No option 'opt'"),
37    (True, None, "No option 'opt' (this option was removed from qutebrowser)"),
38    (False, 'new', "No option 'opt' (this option was renamed to 'new')"),
39])
40def test_no_option_error(deleted, renamed, expected):
41    e = configexc.NoOptionError('opt', deleted=deleted, renamed=renamed)
42    assert e.option == 'opt'
43    assert str(e) == expected
44
45
46def test_no_option_error_clash():
47    with pytest.raises(AssertionError):
48        configexc.NoOptionError('opt', deleted=True, renamed='foo')
49
50
51def test_no_autoconfig_error():
52    e = configexc.NoAutoconfigError('opt')
53    expected = "The opt setting can only be set in config.py!"
54    assert str(e) == expected
55
56
57@pytest.mark.parametrize('raw_backends', [
58    None,
59    {'QtWebEngine': 'Qt 5.11', 'QtWebKit': False}
60])
61def test_backend_error(raw_backends):
62    e = configexc.BackendError('foo', usertypes.Backend.QtWebKit, raw_backends)
63    expected = "The foo setting is not available with the QtWebKit backend!"
64    assert str(e) == expected
65
66
67def test_backend_error_condition():
68    e = configexc.BackendError('foo', usertypes.Backend.QtWebEngine,
69                               {'QtWebEngine': 'Qt 5.11', 'QtWebKit': True})
70    expected = "The foo setting needs Qt 5.11 with the QtWebEngine backend!"
71    assert str(e) == expected
72
73
74def test_no_pattern_error():
75    e = configexc.NoPatternError('foo')
76    expected = "The foo setting does not support URL patterns!"
77    assert str(e) == expected
78
79
80def test_desc_with_text():
81    """Test ConfigErrorDesc.with_text."""
82    old = configexc.ConfigErrorDesc("Error text", Exception("Exception text"))
83    new = old.with_text("additional text")
84    assert str(new) == 'Error text (additional text): Exception text'
85
86
87@pytest.fixture
88def errors():
89    """Get a ConfigFileErrors object."""
90    err1 = configexc.ConfigErrorDesc("Error text 1", Exception("Exception 1"))
91    err2 = configexc.ConfigErrorDesc("Error text 2", Exception("Exception 2"),
92                                     "Fake traceback")
93    return configexc.ConfigFileErrors("config.py", [err1, err2])
94
95
96def test_config_file_errors_str(errors):
97    assert str(errors).splitlines() == [
98        'Errors occurred while reading config.py:',
99        '  Error text 1: Exception 1',
100        '  Error text 2 - Exception: Exception 2',
101    ]
102
103
104def test_config_file_errors_html(errors):
105    html = errors.to_html()
106    assert textwrap.dedent(html) == textwrap.dedent("""
107        Errors occurred while reading config.py:
108
109        <ul>
110
111            <li>
112              <b>Error text 1</b>: Exception 1
113
114            </li>
115
116            <li>
117              <b>Error text 2</b>: Exception 2
118
119                <pre>
120Fake traceback
121                </pre>
122
123            </li>
124
125        </ul>
126    """)
127    # Make sure the traceback is not indented
128    assert '<pre>\nFake traceback\n' in html
129
130
131def test_config_file_errors_fatal():
132    err = configexc.ConfigErrorDesc("Text", Exception("Text"))
133    errors = configexc.ConfigFileErrors("state", [err], fatal=True)
134    assert errors.fatal
135