def test_postprocess_with_extension_on_include(from_file, update):
    conf = mod.ConfDict()
    conf.include = ['foo/bar/baz.ini']
    conf['foo'] = [1, 2, 3]
    incl = mod.ConfDict()
    incl.noextend = True
    incl._extensions = [('foo', [4, 5, 6])]
    from_file.return_value = incl
    conf._postprocess()
    assert conf['foo'] == [1, 2, 3, 4, 5, 6]
def test_get_config_paths_single_string(glob, get_option):
    glob.glob.side_effect = lambda x: [x]
    conf = mod.ConfDict()
    get_option.return_value = 'foo/bar/baz.ini'
    ret = conf._get_config_paths('defaults')
    get_option.assert_called_once_with('config', 'defaults', '')
    assert ret == ['foo/bar/baz.ini']
def test_parse_section_no_clean(get_section):
    conf = mod.ConfDict()
    conf.skip_clean = True
    get_section.return_value = [('foo', 'bar'), ('bar', '1'), ('+baz', '\n12')]
    ret = conf._parse_section('foo')
    assert conf['foo.bar'] == '1'
    assert ret == [('foo.baz', '\n12')]
def test_configure():
    conf = mod.ConfDict()
    conf.configure('/foo/bar/baz.ini', True, True)
    assert conf.path == '/foo/bar/baz.ini'
    assert conf.base_path == '/foo/bar'
    assert conf.skip_clean is True
    assert conf.noextend is True
def test_init_parser(ConfigParser):
    mock_parser = ConfigParser.return_value
    conf = mod.ConfDict()
    conf.path = 'foo/bar/baz.ini'
    assert conf.parser is None
    conf._init_parser()
    assert conf.parser == mock_parser
    mock_parser.read.assert_called_once_with('foo/bar/baz.ini')
def test_parse_section(get_section):
    conf = mod.ConfDict()
    get_section.return_value = [('foo', 'bar'), ('bar', '1')]
    ret = conf._parse_section('foo')
    get_section.assert_called_once_with('foo')
    assert conf['foo.foo'] == 'bar'
    assert conf['foo.bar'] == 1
    assert ret == []
def test_postprocess_include(from_file, update):
    conf = mod.ConfDict()
    conf.base_path = 'test'
    conf.include = ['foo/bar/baz.ini']
    conf._postprocess()
    from_file.assert_called_once_with('foo/bar/baz.ini',
                                      conf.skip_clean,
                                      noextend=True)
    update.assert_called_once_with(from_file.return_value)
def test_process_extension(sections, parse_sections):
    conf = mod.ConfDict()
    sections.return_value = ['foo', 'bar', 'baz']
    parse_sections.side_effect = [[('foo', [1, 2]), ('bar', [2, 3])], [], []]
    conf._process()
    assert conf._extensions == [
        ('foo', [1, 2]),
        ('bar', [2, 3]),
    ]
def test_process(sections, parse_section):
    conf = mod.ConfDict()
    sections.return_value = ['foo', 'bar', 'baz']
    parse_section.return_value = []
    conf._process()
    parse_section.assert_has_calls(
        [mock.call('foo'),
         mock.call('bar'),
         mock.call('baz')])
def test_init_parser_with_fd(ConfigParser):
    from StringIO import StringIO
    mock_parser = ConfigParser.return_value
    conf = mod.ConfDict()
    buff = StringIO()
    conf.path = buff
    assert conf.parser is None
    conf._init_parser()
    assert conf.parser == mock_parser
    mock_parser.readfp.assert_called_once_with(buff)
def test_extend_no_clean():
    conf = mod.ConfDict()
    conf['foo'] = '123'
    conf['bar'] = 'abc'
    conf._extensions = [
        ('foo', '456'),
        ('bar', 'def'),
    ]
    conf.skip_clean = True
    conf._extend()
    assert conf['foo'] == '123456'
    assert conf['bar'] == 'abcdef'
def test_extend():
    conf = mod.ConfDict()
    conf['foo'] = [1, 2, 3]
    conf['bar'] = ['a', 'b', 'c']
    conf._extensions = [
        ('foo', [4, 5, 6]),
        ('bar', ['d', 'e', 'f']),
    ]
    conf._extend()
    assert conf['foo'] == [1, 2, 3, 4, 5, 6]
    assert conf['bar'] == ['a', 'b', 'c', 'd', 'e', 'f']
    # After extending is performed, extensions are cleared
    assert conf._extensions == []
def test_extend_noexted():
    conf = mod.ConfDict()
    conf.noextend = True
    conf['foo'] = [1, 2, 3]
    conf['bar'] = ['a', 'b', 'c']
    conf._extensions = [
        ('foo', [4, 5, 6]),
        ('bar', ['d', 'e', 'f']),
    ]
    conf._extend()
    assert conf['foo'] == [1, 2, 3]
    assert conf['bar'] == ['a', 'b', 'c']
    assert conf._extensions == [
        ('foo', [4, 5, 6]),
        ('bar', ['d', 'e', 'f']),
    ]
    conf.noextend = False
    conf._extend()
    assert conf['foo'] == [1, 2, 3, 4, 5, 6]
    assert conf['bar'] == ['a', 'b', 'c', 'd', 'e', 'f']
def test_load(postprocess, process, preprocess, check, init):
    conf = mod.ConfDict()
    conf.load()
    # Load is just a wrapper that calls all these methods
    for meth in postprocess, process, preprocess, check, init:
        meth.assert_called_once_with()
def test_parse_section_extend(get_section):
    conf = mod.ConfDict()
    get_section.return_value = [('foo', 'bar'), ('bar', '1'), ('+baz', '\n12')]
    ret = conf._parse_section('foo')
    assert ret == [('foo.baz', [12])]
def test_get_config_paths_no_return(get_option):
    conf = mod.ConfDict()
    get_option.return_value = ''
    ret = conf._get_config_paths('defaults')
    get_option.assert_called_once_with('config', 'defaults', '')
    assert ret == []
def test_setdefaults():
    conf = mod.ConfDict()
    conf['foo'] = 'bar'
    conf.setdefaults({'foo': 1, 'bar': 2})
    assert conf['foo'] == 'bar'
    assert conf['bar'] == 2
def test_postprocess_extends(extend):
    conf = mod.ConfDict()
    conf._postprocess()
    extend.assert_called_once_with()
def test_import_missing():
    conf = mod.ConfDict()
    # This should not raise:
    ret = conf.import_from_file('missing.ini', ignore_missing=True)
    assert ret == {}
def get_mock_conf():
    mock_parser = mock.Mock(specs=mod.ConfigParser)
    conf = mod.ConfDict()
    conf.parser = mock_parser
    return conf