python-mylib/tests/test_config.py
2023-01-09 13:33:14 +01:00

347 lines
10 KiB
Python

# pylint: disable=redefined-outer-name,missing-function-docstring,protected-access,global-statement
# pylint: disable=global-variable-not-assigned
""" Tests on config lib """
import logging
import os
import configparser
import pytest
from mylib.config import Config, ConfigSection
from mylib.config import BooleanOption
from mylib.config import StringOption
runned = {}
def test_config_init_default_args():
appname = 'Test app'
config = Config(appname)
assert config.appname == appname
assert config.version == '0.0'
assert config.encoding == 'utf-8'
def test_config_init_custom_args():
appname = 'Test app'
version = '1.43'
encoding = 'ISO-8859-1'
config = Config(appname, version=version, encoding=encoding)
assert config.appname == appname
assert config.version == version
assert config.encoding == encoding
def test_add_section_default_args():
config = Config('Test app')
name = 'test_section'
section = config.add_section(name)
assert isinstance(section, ConfigSection)
assert config.sections[name] == section
assert section.name == name
assert section.comment is None
assert section.order == 10
def test_add_section_custom_args():
config = Config('Test app')
name = 'test_section'
comment = 'Test'
order = 20
section = config.add_section(name, comment=comment, order=order)
assert isinstance(section, ConfigSection)
assert section.name == name
assert section.comment == comment
assert section.order == order
def test_add_section_with_callback():
config = Config('Test app')
name = 'test_section'
global runned
runned['test_add_section_with_callback'] = False
def test_callback(loaded_config):
global runned
assert loaded_config == config
assert runned['test_add_section_with_callback'] is False
runned['test_add_section_with_callback'] = True
section = config.add_section(name, loaded_callback=test_callback)
assert isinstance(section, ConfigSection)
assert test_callback in config._loaded_callbacks
assert runned['test_add_section_with_callback'] is False
config.parse_arguments_options(argv=[], create=False)
assert runned['test_add_section_with_callback'] is True
assert test_callback in config._loaded_callbacks_executed
# Try to execute again to verify callback is not runned again
config._loaded()
def test_add_section_with_callback_already_loaded():
config = Config('Test app')
name = 'test_section'
config.parse_arguments_options(argv=[], create=False)
global runned
runned['test_add_section_with_callback_already_loaded'] = False
def test_callback(loaded_config):
global runned
assert loaded_config == config
assert runned['test_add_section_with_callback_already_loaded'] is False
runned['test_add_section_with_callback_already_loaded'] = True
section = config.add_section(name, loaded_callback=test_callback)
assert isinstance(section, ConfigSection)
assert runned['test_add_section_with_callback_already_loaded'] is True
assert test_callback in config._loaded_callbacks
assert test_callback in config._loaded_callbacks_executed
# Try to execute again to verify callback is not runned again
config._loaded()
def test_add_option_default_args():
config = Config('Test app')
section = config.add_section('my_section')
assert isinstance(section, ConfigSection)
name = 'my_option'
option = section.add_option(StringOption, name)
assert isinstance(option, StringOption)
assert name in section.options and section.options[name] == option
assert option.config == config
assert option.section == section
assert option.name == name
assert option.default is None
assert option.comment is None
assert option.no_arg is False
assert option.arg is None
assert option.short_arg is None
assert option.arg_help is None
def test_add_option_custom_args():
config = Config('Test app')
section = config.add_section('my_section')
assert isinstance(section, ConfigSection)
name = 'my_option'
kwargs = dict(
default='default value',
comment='my comment',
no_arg=True,
arg='--my-option',
short_arg='-M',
arg_help='My help'
)
option = section.add_option(StringOption, name, **kwargs)
assert isinstance(option, StringOption)
assert name in section.options and section.options[name] == option
assert option.config == config
assert option.section == section
assert option.name == name
for arg, value in kwargs.items():
assert getattr(option, arg) == value
def test_defined():
config = Config('Test app')
section_name = 'my_section'
opt_name = 'my_option'
assert not config.defined(section_name, opt_name)
section = config.add_section('my_section')
assert isinstance(section, ConfigSection)
section.add_option(StringOption, opt_name)
assert config.defined(section_name, opt_name)
def test_isset():
config = Config('Test app')
section_name = 'my_section'
opt_name = 'my_option'
assert not config.isset(section_name, opt_name)
section = config.add_section('my_section')
assert isinstance(section, ConfigSection)
option = section.add_option(StringOption, opt_name)
assert not config.isset(section_name, opt_name)
config.parse_arguments_options(argv=[option.parser_argument_name, 'value'], create=False)
assert config.isset(section_name, opt_name)
def test_not_isset():
config = Config('Test app')
section_name = 'my_section'
opt_name = 'my_option'
assert not config.isset(section_name, opt_name)
section = config.add_section('my_section')
assert isinstance(section, ConfigSection)
section.add_option(StringOption, opt_name)
assert not config.isset(section_name, opt_name)
config.parse_arguments_options(argv=[], create=False)
assert not config.isset(section_name, opt_name)
def test_get():
config = Config('Test app')
section_name = 'my_section'
opt_name = 'my_option'
opt_value = 'value'
section = config.add_section('my_section')
option = section.add_option(StringOption, opt_name)
config.parse_arguments_options(argv=[option.parser_argument_name, opt_value], create=False)
assert config.get(section_name, opt_name) == opt_value
def test_get_default():
config = Config('Test app')
section_name = 'my_section'
opt_name = 'my_option'
opt_default_value = 'value'
section = config.add_section('my_section')
section.add_option(StringOption, opt_name, default=opt_default_value)
config.parse_arguments_options(argv=[], create=False)
assert config.get(section_name, opt_name) == opt_default_value
def test_logging_splited_stdout_stderr(capsys):
config = Config('Test app')
config.parse_arguments_options(argv=['-C', '-v'], create=False)
info_msg = "[info]"
err_msg = "[error]"
logging.getLogger().info(info_msg)
logging.getLogger().error(err_msg)
captured = capsys.readouterr()
assert info_msg in captured.out
assert info_msg not in captured.err
assert err_msg in captured.err
assert err_msg not in captured.out
#
# Test option types
#
@pytest.fixture()
def config_with_file(tmpdir):
config = Config('Test app')
config_dir = tmpdir.mkdir('config')
config_file = config_dir.join('config.ini')
config.save(os.path.join(config_file.dirname, config_file.basename))
return config
def generate_mock_input(expected_prompt, input_value):
def mock_input(self, prompt): # pylint: disable=unused-argument
assert prompt == expected_prompt
return input_value
return mock_input
# Boolean option
def test_boolean_option_from_config(config_with_file):
section = config_with_file.add_section('test')
default = True
option = section.add_option(
BooleanOption, 'test_bool', default=default)
config_with_file.save()
option.set(not default)
assert option._from_config is not default
option.set(default)
assert not option._isset_in_config_file
with pytest.raises(configparser.NoOptionError):
assert option._from_config is default
def test_boolean_option_ask_value(mocker):
config = Config('Test app')
section = config.add_section('test')
name = 'test_bool'
option = section.add_option(
BooleanOption, name, default=True)
mocker.patch(
'mylib.config.BooleanOption._get_user_input',
generate_mock_input(f'{name}: [Y/n] ', 'y')
)
assert option.ask_value(set_it=False) is True
mocker.patch(
'mylib.config.BooleanOption._get_user_input',
generate_mock_input(f'{name}: [Y/n] ', 'Y')
)
assert option.ask_value(set_it=False) is True
mocker.patch(
'mylib.config.BooleanOption._get_user_input',
generate_mock_input(f'{name}: [Y/n] ', '')
)
assert option.ask_value(set_it=False) is True
mocker.patch(
'mylib.config.BooleanOption._get_user_input',
generate_mock_input(f'{name}: [Y/n] ', 'n')
)
assert option.ask_value(set_it=False) is False
mocker.patch(
'mylib.config.BooleanOption._get_user_input',
generate_mock_input(f'{name}: [Y/n] ', 'N')
)
assert option.ask_value(set_it=False) is False
def test_boolean_option_to_config():
config = Config('Test app')
section = config.add_section('test')
default = True
option = section.add_option(BooleanOption, 'test_bool', default=default)
assert option.to_config(True) == 'true'
assert option.to_config(False) == 'false'
def test_boolean_option_export_to_config(config_with_file):
section = config_with_file.add_section('test')
name = 'test_bool'
comment = 'Test boolean'
default = True
option = section.add_option(
BooleanOption, name, default=default, comment=comment)
assert option.export_to_config() == f"""# {comment}
# Default: {str(default).lower()}
# {name} =
"""
option.set(not default)
assert option.export_to_config() == f"""# {comment}
# Default: {str(default).lower()}
{name} = {str(not default).lower()}
"""
option.set(default)
assert option.export_to_config() == f"""# {comment}
# Default: {str(default).lower()}
# {name} =
"""