From 5d63dfb24c5e42bafd01289adba2d5ceb25342b2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 19 Feb 2018 20:26:38 +0100 Subject: [PATCH] Start fixing test_configfiles.py --- tests/unit/config/test_configfiles.py | 157 ++++++++++++++------------ 1 file changed, 86 insertions(+), 71 deletions(-) diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index 06633ffc7..e71c7498d 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -38,6 +38,36 @@ def configdata_init(): configdata.init() +class AutoConfigHelper: + + """A helper to easily create/validate autoconfig.yml files.""" + + def __init__(self, config_tmpdir): + self.fobj = config_tmpdir / 'autoconfig.yml' + + def write(self, values): + data = {'config_version': 1, 'settings': values} + with self.fobj.open('w', encoding='utf-8') as f: + utils.yaml_dump(data, f) + + def write_raw(self, text): + self.fobj.write_text(text, encoding='utf-8', ensure=True) + + def read(self): + with self.fobj.open('r', encoding='utf-8') as f: + data = utils.yaml_load(f) + assert data['config_version'] == 1 + return data['settings'] + + def read_raw(self): + return self.fobj.read_text('utf-8') + + +@pytest.fixture +def autoconfig(config_tmpdir): + return AutoConfigHelper(config_tmpdir) + + @pytest.mark.parametrize('old_data, insert, new_data', [ (None, False, '[general]\n\n[geometry]\n\n'), ('[general]\nfooled = true', False, '[general]\n\n[geometry]\n\n'), @@ -75,49 +105,44 @@ class TestYaml: @pytest.mark.parametrize('old_config', [ None, - 'global:\n colors.hints.fg: magenta', + {'colors.hints.fg': {'global': 'magenta'}} ]) @pytest.mark.parametrize('insert', [True, False]) - def test_yaml_config(self, yaml, config_tmpdir, old_config, insert): - autoconfig = config_tmpdir / 'autoconfig.yml' + def test_yaml_config(self, yaml, autoconfig, old_config, insert): if old_config is not None: - autoconfig.write_text(old_config, 'utf-8') + autoconfig.write(old_config) yaml.load() if insert: - yaml['tabs.show'] = 'never' + yaml.set_obj('tabs.show', 'never') yaml._save() if not insert and old_config is None: lines = [] else: - text = autoconfig.read_text('utf-8') - lines = text.splitlines() + data = autoconfig.read() + lines = autoconfig.read_raw().splitlines() if insert: assert lines[0].startswith('# DO NOT edit this file by hand,') - assert 'config_version: {}'.format(yaml.VERSION) in lines - - assert 'global:' in lines print(lines) - if 'magenta' in (old_config or ''): - assert ' colors.hints.fg: magenta' in lines + if old_config is not None: + assert data['colors.hints.fg'] == {'global': 'magenta'} if insert: - assert ' tabs.show: never' in lines + assert data['tabs.show'] == {'global': 'never'} def test_init_save_manager(self, yaml, fake_save_manager): yaml.init_save_manager(fake_save_manager) fake_save_manager.add_saveable.assert_called_with( 'yaml-config', unittest.mock.ANY, unittest.mock.ANY) - def test_unknown_key(self, yaml, config_tmpdir): + def test_unknown_key(self, yaml, autoconfig): """An unknown setting should show an error.""" - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text('global:\n hello: world', encoding='utf-8') + autoconfig.write({'hello': {'global': 'world'}}) with pytest.raises(configexc.ConfigFileErrors) as excinfo: yaml.load() @@ -127,10 +152,9 @@ class TestYaml: assert error.text == "While loading options" assert str(error.exception) == "Unknown option hello" - def test_multiple_unknown_keys(self, yaml, config_tmpdir): + def test_multiple_unknown_keys(self, yaml, autoconfig): """With multiple unknown settings, all should be shown.""" - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text('global:\n one: 1\n two: 2', encoding='utf-8') + autoconfig.write({'one': {'global': 1}, 'two': {'global': 2}}) with pytest.raises(configexc.ConfigFileErrors) as excinfo: yaml.load() @@ -141,23 +165,21 @@ class TestYaml: assert str(error1.exception) == "Unknown option one" assert str(error2.exception) == "Unknown option two" - def test_deleted_key(self, monkeypatch, yaml, config_tmpdir): + def test_deleted_key(self, monkeypatch, yaml, autoconfig): """A key marked as deleted should be removed.""" - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text('global:\n hello: world', encoding='utf-8') + autoconfig.write({'hello': {'global': 'world'}}) monkeypatch.setattr(configdata.MIGRATIONS, 'deleted', ['hello']) yaml.load() yaml._save() - lines = autoconfig.read_text('utf-8').splitlines() - assert ' hello: world' not in lines + data = autoconfig.read() + assert not data - def test_renamed_key(self, monkeypatch, yaml, config_tmpdir): + def test_renamed_key(self, monkeypatch, yaml, autoconfig): """A key marked as renamed should be renamed properly.""" - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text('global:\n old: value', encoding='utf-8') + autoconfig.write({'old': {'global': 'value'}}) monkeypatch.setattr(configdata.MIGRATIONS, 'renamed', {'old': 'tabs.show'}) @@ -165,29 +187,25 @@ class TestYaml: yaml.load() yaml._save() - lines = autoconfig.read_text('utf-8').splitlines() - assert ' old: value' not in lines - assert ' tabs.show: value' in lines + data = autoconfig.read() + assert data == {'tabs.show': {'global': 'value'}} @pytest.mark.parametrize('persist', [True, False]) - def test_merge_persist(self, yaml, config_tmpdir, persist): + def test_merge_persist(self, yaml, autoconfig, persist): """Tests for migration of tabs.persist_mode_on_change.""" - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text('global:\n tabs.persist_mode_on_change: {}'. - format(persist), encoding='utf-8') + autoconfig.write({'tabs.persist_mode_on_change': {'global': persist}}) yaml.load() yaml._save() - lines = autoconfig.read_text('utf-8').splitlines() + data = autoconfig.read() + assert 'tabs.persist_mode_on_change' not in data mode = 'persist' if persist else 'normal' - assert ' tabs.persist_mode_on_change:' not in lines - assert ' tabs.mode_on_change: {}'.format(mode) in lines + assert data['tabs.mode_on_change'] == mode def test_renamed_key_unknown_target(self, monkeypatch, yaml, - config_tmpdir): + autoconfig): """A key marked as renamed with invalid name should raise an error.""" - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text('global:\n old: value', encoding='utf-8') + autoconfig.write_text({'old': {'global': 'value'}}) monkeypatch.setattr(configdata.MIGRATIONS, 'renamed', {'old': 'new'}) @@ -202,7 +220,7 @@ class TestYaml: @pytest.mark.parametrize('old_config', [ None, - 'global:\n colors.hints.fg: magenta', + {'colors.hints.fg': {'global': 'magenta'}}, ]) @pytest.mark.parametrize('key, value', [ ('colors.hints.fg', 'green'), @@ -210,18 +228,18 @@ class TestYaml: ('confirm_quit', True), ('confirm_quit', False), ]) - def test_changed(self, yaml, qtbot, config_tmpdir, old_config, key, value): - autoconfig = config_tmpdir / 'autoconfig.yml' + def test_changed(self, yaml, qtbot, autoconfig, + old_config, key, value): if old_config is not None: - autoconfig.write_text(old_config, 'utf-8') + autoconfig.write(old_config) yaml.load() with qtbot.wait_signal(yaml.changed): - yaml[key] = value + yaml.set_obj(key, value) assert key in yaml - assert yaml[key] == value + assert yaml._values[key].get_for_url(fallback=False) == value yaml._save() @@ -229,42 +247,40 @@ class TestYaml: yaml.load() assert key in yaml - assert yaml[key] == value + assert yaml._values[key].get_for_url(fallback=False) == value def test_iter(self, yaml): - yaml['foo'] = 23 - yaml['bar'] = 42 + yaml.set_obj('foo', 23) + yaml.set_obj('bar', 42) assert list(iter(yaml)) == [('bar', 42), ('foo', 23)] @pytest.mark.parametrize('old_config', [ None, - 'global:\n colors.hints.fg: magenta', + {'colors.hints.fg': {'global': 'magenta'}}, ]) - def test_unchanged(self, yaml, config_tmpdir, old_config): - autoconfig = config_tmpdir / 'autoconfig.yml' + def test_unchanged(self, yaml, autoconfig, old_config): mtime = None if old_config is not None: - autoconfig.write_text(old_config, 'utf-8') - mtime = autoconfig.stat().mtime + autoconfig.write(old_config) + mtime = autoconfig.fobj.stat().mtime yaml.load() yaml._save() if old_config is None: - assert not autoconfig.exists() + assert not autoconfig.fobj.exists() else: - assert autoconfig.stat().mtime == mtime + assert autoconfig.fobj.stat().mtime == mtime @pytest.mark.parametrize('line, text, exception', [ ('%', 'While parsing', 'while scanning a directive'), - ('global: 42', 'While loading data', "'global' object is not a dict"), + ('settings: 42', 'While loading data', "'settings' object is not a dict"), ('foo: 42', 'While loading data', - "Toplevel object does not contain 'global' key"), + "Toplevel object does not contain 'settings' key"), ('42', 'While loading data', "Toplevel object is not a dict"), ]) - def test_invalid(self, yaml, config_tmpdir, line, text, exception): - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.write_text(line, 'utf-8', ensure=True) + def test_invalid(self, yaml, autoconfig, line, text, exception): + autoconfig.write_raw(line) with pytest.raises(configexc.ConfigFileErrors) as excinfo: yaml.load() @@ -275,11 +291,10 @@ class TestYaml: assert str(error.exception).splitlines()[0] == exception assert error.traceback is None - def test_oserror(self, yaml, config_tmpdir): - autoconfig = config_tmpdir / 'autoconfig.yml' - autoconfig.ensure() - autoconfig.chmod(0) - if os.access(str(autoconfig), os.R_OK): + def test_oserror(self, yaml, autoconfig): + autoconfig.fobj.ensure() + autoconfig.fobj.chmod(0) + if os.access(str(autoconfig.fobj), os.R_OK): # Docker container or similar pytest.skip("File was still readable") @@ -292,22 +307,22 @@ class TestYaml: assert isinstance(error.exception, OSError) assert error.traceback is None - def test_unset(self, yaml, qtbot, config_tmpdir): + def test_unset(self, yaml, qtbot): name = 'tabs.show' - yaml[name] = 'never' + yaml.set_obj(name, 'never') with qtbot.wait_signal(yaml.changed): yaml.unset(name) assert name not in yaml - def test_unset_never_set(self, yaml, qtbot, config_tmpdir): + def test_unset_never_set(self, yaml, qtbot): with qtbot.assert_not_emitted(yaml.changed): yaml.unset('tabs.show') - def test_clear(self, yaml, qtbot, config_tmpdir): + def test_clear(self, yaml, qtbot): name = 'tabs.show' - yaml[name] = 'never' + yaml.set_obj(name, 'never') with qtbot.wait_signal(yaml.changed): yaml.clear()