From 57bc0d56d7e741e1e99d96f14e7ab93232440a16 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 30 Jan 2021 09:13:47 +0100 Subject: Adding upstream version 2.1.0. Signed-off-by: Daniel Baumann --- tests/test_config.py | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 tests/test_config.py (limited to 'tests/test_config.py') diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..035e311 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +"""Test the cli_helpers.config module.""" + +from __future__ import unicode_literals +import os + +from unittest.mock import MagicMock +import pytest + +from cli_helpers.compat import MAC, text_type, WIN +from cli_helpers.config import (Config, DefaultConfigValidationError, + get_system_config_dirs, get_user_config_dir, + _pathify) +from .utils import with_temp_dir + +APP_NAME, APP_AUTHOR = 'Test', 'Acme' +TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), 'config_data') +DEFAULT_CONFIG = { + 'section': { + 'test_boolean_default': 'True', + 'test_string_file': '~/myfile', + 'test_option': 'foobar' + }, + 'section2': {} +} +DEFAULT_VALID_CONFIG = { + 'section': { + 'test_boolean_default': True, + 'test_string_file': '~/myfile', + 'test_option': 'foobar' + }, + 'section2': {} +} + + +def _mocked_user_config(temp_dir, *args, **kwargs): + config = Config(*args, **kwargs) + config.user_config_file = MagicMock(return_value=os.path.join( + temp_dir, config.filename)) + return config + + +def test_user_config_dir(): + """Test that the config directory is a string with the app name in it.""" + if 'XDG_CONFIG_HOME' in os.environ: + del os.environ['XDG_CONFIG_HOME'] + config_dir = get_user_config_dir(APP_NAME, APP_AUTHOR) + assert isinstance(config_dir, text_type) + assert (config_dir.endswith(APP_NAME) or + config_dir.endswith(_pathify(APP_NAME))) + + +def test_sys_config_dirs(): + """Test that the sys config directories are returned correctly.""" + if 'XDG_CONFIG_DIRS' in os.environ: + del os.environ['XDG_CONFIG_DIRS'] + config_dirs = get_system_config_dirs(APP_NAME, APP_AUTHOR) + assert isinstance(config_dirs, list) + assert (config_dirs[0].endswith(APP_NAME) or + config_dirs[0].endswith(_pathify(APP_NAME))) + + +@pytest.mark.skipif(not WIN, reason="requires Windows") +def test_windows_user_config_dir_no_roaming(): + """Test that Windows returns the user config directory without roaming.""" + config_dir = get_user_config_dir(APP_NAME, APP_AUTHOR, roaming=False) + assert isinstance(config_dir, text_type) + assert config_dir.endswith(APP_NAME) + assert 'Local' in config_dir + + +@pytest.mark.skipif(not MAC, reason="requires macOS") +def test_mac_user_config_dir_no_xdg(): + """Test that macOS returns the user config directory without XDG.""" + config_dir = get_user_config_dir(APP_NAME, APP_AUTHOR, force_xdg=False) + assert isinstance(config_dir, text_type) + assert config_dir.endswith(APP_NAME) + assert 'Library' in config_dir + + +@pytest.mark.skipif(not MAC, reason="requires macOS") +def test_mac_system_config_dirs_no_xdg(): + """Test that macOS returns the system config directories without XDG.""" + config_dirs = get_system_config_dirs(APP_NAME, APP_AUTHOR, force_xdg=False) + assert isinstance(config_dirs, list) + assert config_dirs[0].endswith(APP_NAME) + assert 'Library' in config_dirs[0] + + +def test_config_reading_raise_errors(): + """Test that instantiating Config will raise errors when appropriate.""" + with pytest.raises(ValueError): + Config(APP_NAME, APP_AUTHOR, 'test_config', write_default=True) + + with pytest.raises(ValueError): + Config(APP_NAME, APP_AUTHOR, 'test_config', validate=True) + + with pytest.raises(TypeError): + Config(APP_NAME, APP_AUTHOR, 'test_config', default=b'test') + + +def test_config_user_file(): + """Test that the Config user_config_file is appropriate.""" + config = Config(APP_NAME, APP_AUTHOR, 'test_config') + assert (get_user_config_dir(APP_NAME, APP_AUTHOR) in + config.user_config_file()) + + +def test_config_reading_default_dict(): + """Test that the Config constructor will read in defaults from a dict.""" + default = {'main': {'foo': 'bar'}} + config = Config(APP_NAME, APP_AUTHOR, 'test_config', default=default) + assert config.data == default + + +def test_config_reading_no_default(): + """Test that the Config constructor will work without any defaults.""" + config = Config(APP_NAME, APP_AUTHOR, 'test_config') + assert config.data == {} + + +def test_config_reading_default_file(): + """Test that the Config will work with a default file.""" + config = Config(APP_NAME, APP_AUTHOR, 'test_config', + default=os.path.join(TEST_DATA_DIR, 'configrc')) + config.read_default_config() + assert config.data == DEFAULT_CONFIG + + +def test_config_reading_configspec(): + """Test that the Config default file will work with a configspec.""" + config = Config(APP_NAME, APP_AUTHOR, 'test_config', validate=True, + default=os.path.join(TEST_DATA_DIR, 'configspecrc')) + config.read_default_config() + assert config.data == DEFAULT_VALID_CONFIG + + +def test_config_reading_configspec_with_error(): + """Test that reading an invalid configspec raises and exception.""" + with pytest.raises(DefaultConfigValidationError): + config = Config(APP_NAME, APP_AUTHOR, 'test_config', validate=True, + default=os.path.join(TEST_DATA_DIR, + 'invalid_configspecrc')) + config.read_default_config() + + +@with_temp_dir +def test_write_and_read_default_config(temp_dir=None): + config_file = 'test_config' + default_file = os.path.join(TEST_DATA_DIR, 'configrc') + temp_config_file = os.path.join(temp_dir, config_file) + + config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, config_file, + default=default_file) + config.read_default_config() + config.write_default_config() + + user_config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, + config_file, default=default_file) + user_config.read() + assert temp_config_file in user_config.config_filenames + assert user_config == config + + with open(temp_config_file) as f: + contents = f.read() + assert '# Test file comment' in contents + assert '# Test section comment' in contents + assert '# Test field comment' in contents + assert '# Test field commented out' in contents + + +@with_temp_dir +def test_write_and_read_default_config_from_configspec(temp_dir=None): + config_file = 'test_config' + default_file = os.path.join(TEST_DATA_DIR, 'configspecrc') + temp_config_file = os.path.join(temp_dir, config_file) + + config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, config_file, + default=default_file, validate=True) + config.read_default_config() + config.write_default_config() + + user_config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, + config_file, default=default_file, + validate=True) + user_config.read() + assert temp_config_file in user_config.config_filenames + assert user_config == config + + with open(temp_config_file) as f: + contents = f.read() + assert '# Test file comment' in contents + assert '# Test section comment' in contents + assert '# Test field comment' in contents + assert '# Test field commented out' in contents + + +@with_temp_dir +def test_overwrite_default_config_from_configspec(temp_dir=None): + config_file = 'test_config' + default_file = os.path.join(TEST_DATA_DIR, 'configspecrc') + temp_config_file = os.path.join(temp_dir, config_file) + + config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, config_file, + default=default_file, validate=True) + config.read_default_config() + config.write_default_config() + + with open(temp_config_file, 'a') as f: + f.write('--APPEND--') + + config.write_default_config() + + with open(temp_config_file) as f: + assert '--APPEND--' in f.read() + + config.write_default_config(overwrite=True) + + with open(temp_config_file) as f: + assert '--APPEND--' not in f.read() + + +def test_read_invalid_config_file(): + config_file = 'invalid_configrc' + + config = _mocked_user_config(TEST_DATA_DIR, APP_NAME, APP_AUTHOR, + config_file) + config.read() + assert 'section' in config + assert 'test_string_file' in config['section'] + assert 'test_boolean_default' not in config['section'] + assert 'section2' in config + + +@with_temp_dir +def test_write_to_user_config(temp_dir=None): + config_file = 'test_config' + default_file = os.path.join(TEST_DATA_DIR, 'configrc') + temp_config_file = os.path.join(temp_dir, config_file) + + config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, config_file, + default=default_file) + config.read_default_config() + config.write_default_config() + + with open(temp_config_file) as f: + assert 'test_boolean_default = True' in f.read() + + config['section']['test_boolean_default'] = False + config.write() + + with open(temp_config_file) as f: + assert 'test_boolean_default = False' in f.read() + + +@with_temp_dir +def test_write_to_outfile(temp_dir=None): + config_file = 'test_config' + outfile = os.path.join(temp_dir, 'foo') + default_file = os.path.join(TEST_DATA_DIR, 'configrc') + + config = _mocked_user_config(temp_dir, APP_NAME, APP_AUTHOR, config_file, + default=default_file) + config.read_default_config() + config.write_default_config() + + config['section']['test_boolean_default'] = False + config.write(outfile=outfile) + + with open(outfile) as f: + assert 'test_boolean_default = False' in f.read() -- cgit v1.2.3