예제 #1
0
def test_source_get():
    config = DictSource({'a': 1})

    assert config.get('a') == 1
    assert config.get('nonexisting') is None
    assert config.get('nonexisting', 'default') == 'default'
    assert 'nonexisting' not in config
예제 #2
0
def test_reverse_source_order(reverse, values):
    sources = [
        DictSource({
            'a': 1,
            'b': {}
        }),
        DictSource({
            'a': 10,
            'b': {
                'c': 20
            }
        }),
        DictSource({
            'a': 100,
            'b': {
                'c': 200
            }
        }),
        DictSource({
            'a': 1000,
            'b': {}
        }),
    ]

    config = StackedConfig(*sources, reverse=reverse)

    assert config.a == values[0]
    assert config.b.c == values[1]
예제 #3
0
def test_write_stacked_source():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'x': 6, 'b': {'y': 7, 'd': {'e': 8}}})
    config = StackedConfig(source1, source2)

    assert config.a == 1
    assert config.b.c == 2
    assert config.b.y == 7

    config.a = 10
    config['x'] = 60
    config['b'].c = 20
    config.b['y'] = 70
    config.b['m'] = 'n'  # add new key
    config.b.d.e = 80

    assert config.a == 10
    assert config.x == 60
    assert config.b.c == 20
    assert config.b.y == 70
    assert config.b.m == 'n'
    assert config.b.d.e == 80

    assert source1.a == 10
    assert source1.b.c == 20

    assert source2.x == 60
    assert source2.b.y == 70
    assert source2.b.m == 'n'
    assert source2.b.d.e == 80
예제 #4
0
def test_read_stacked_sources():
    config = StackedConfig(DictSource({
        'a': 1,
        'b': {
            'c': 2
        }
    }), DictSource({
        'x': 6,
        'b': {
            'y': 7,
            'd': {
                'e': 8
            }
        }
    }))

    assert config.a == 1
    assert config.x == 6
    assert config.b.c == 2
    assert config.b.y == 7

    assert config['a'] == 1
    assert config['x'] == 6
    assert config['b'].c == 2
    assert config.b['y'] == 7
    assert config.b.d.e == 8
예제 #5
0
def test_read_stacked_sources_with_strategies():
    config = StackedConfig(
        DictSource({
            'a': 1,
            'x': [5, 6],
            'b': {
                'c': 2,
                'd': [3, 4]
            }
        }),
        DictSource({
            'a': 10,
            'x': [50, 60],
            'b': {
                'c': 20,
                'd': [30, 40]
            }
        }),
        strategy_map={
            'a': strategies.add,
            'x': strategies.collect,  # keep lists intact
            'c': strategies.collect,  # collect values into list
            'd': strategies.merge,  # merge lists
        })

    assert config.a == 11
    assert config.x == [[50, 60], [5, 6]]
    assert config.b.c == [20, 2]
    assert config.b.d == [30, 40, 3, 4]
예제 #6
0
def test_add_source_after_instantiation():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'m': 10, 'b': {'o': 20}})

    sources = SourceList(source1)
    sources.append(source2)

    assert list(sources) == [source2, source1]
예제 #7
0
def test_iterate_sources_with_keychain():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'m': 10, 'b': {'o': 20}})
    subsource1 = DictSource({'c': 2})
    subsource2 = DictSource({'o': 20})

    sources = SourceList(source1, source2, keychain=['b'])

    assert list(sources) == [subsource2, subsource1]
예제 #8
0
def test_iterate_sources():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'m': 10, 'b': {'o': 20}})

    sources = SourceList(source1, source2)

    # sources will be returned reversed to start with the highest
    # priority
    assert list(sources) == [source2, source1]
예제 #9
0
def test_source_setdefault_as_subsection():
    config = DictSource()

    with pytest.raises(AttributeError):
        config.a.b = 1

    config.setdefault('a', {}).b = 1

    assert config.a.b == 1
예제 #10
0
def test_change_source_after_instantiation():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'m': 10, 'b': {'o': 20}})
    updated = DictSource({'x': 100, 'b': {'y': 200}})

    sources = SourceList(source1, source2)
    sources[0] = updated

    assert list(sources) == [source2, updated]
예제 #11
0
def test_read_stacked_sources_with_joining_strategy():
    source1 = DictSource({'path': '/path/to/default/file'})
    source2 = DictSource({'path': '/path/to/user/file'})

    config = StackedConfig(
        source1,
        source2,
        strategy_map={'path': strategies.make_join(separator=':')})

    assert config.path == '/path/to/user/file:/path/to/default/file'
예제 #12
0
def test_builtin_converters(converter, value, customized, reset):
    data = {'a': value}
    config = DictSource(data, converters=[converter])

    assert config.a == customized

    del config.a
    config.a = customized

    assert config._data['a'] == reset
예제 #13
0
def test_read_complex_stacked_sources(monkeypatch):
    monkeypatch.setenv('MVP1_A', '1000')
    monkeypatch.setenv('MVP2_B_M_E', '4000')

    config = StackedConfig(
        Environment('MVP1_'),  # untyped shadowing
        DictSource({
            'a': 1,
            'b': {
                'c': 2,
                'e': 400
            }
        }),
        DictSource({
            'x': 6,
            'b': {
                'y': 7,
                'd': {
                    'e': 8
                }
            }
        }),
        DictSource({
            'a': 100,
            'b': {
                'm': {
                    'e': 800
                }
            }
        }),  # shadowing
        DictSource({
            'x': 'x',
            'b': {
                'y': 0.7,
                'd': 800
            }
        }),  # type changing
        Environment('MVP2_'),  # untyped shadowing
    )

    assert config.a == 100
    assert config.x == 'x'  # changed int to str
    assert config.b.c == 2
    assert config.b.y == 0.7  # changed int to float
    assert config.b.d == 800  # changed subsection (dict) to single value
    assert config.b.e == 400  # 'e' should not be shadowed by other 'e'
    assert config.b.m.e == 4000  # shadowed by untyped but casted to type

    with pytest.raises(AttributeError) as exc_info:
        config.b.x

    # config.b.d.e overrides a dict with a value
    with pytest.raises(AttributeError) as exc_info:
        config.b.d.e
    assert "no attribute 'e'" in str(exc_info.value)
예제 #14
0
def test_read_stacked_sources_with_strategies_for_none_values():
    config = StackedConfig(DictSource({'a': None}),
                           DictSource({'a': None}),
                           strategy_map={
                               'a': strategies.collect,
                           })

    result = [None, None]

    assert config.a == result
    assert list(config.items()) == [('a', result)]
예제 #15
0
def test_write_to_empty_sources():
    source1 = DictSource(auto_subsection=True)
    source2 = DictSource()
    config = StackedConfig(source2, source1)

    config.a = 10
    config['b'].c = 20

    assert source1.a == 10
    assert source1.b.c == 20
    assert source2.dump() == {}
예제 #16
0
def test_remove_source_after_instantiation():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'m': 10, 'b': {'o': 20}})

    sources = SourceList(source1, source2)
    sources.remove(source1)

    assert list(sources) == [source2]

    del sources[0]

    assert list(sources) == []
예제 #17
0
def test_read_source_with_converters():
    data = {'a': 1, 'b': {'c': 2}}
    converter_list = [
        ('a', str, int),
        ('c', lambda v: 2 * v, lambda v: v / 2),
    ]
    config = DictSource(data, converters=converter_list)

    assert config.a == '1'
    assert config.b.c == 4

    assert config.dump() == {'a': '1', 'b': {'c': 4}}
예제 #18
0
def test_write_source_with_converters():
    data = {'a': 1, 'b': {'c': 2}}
    converter_list = [
        ('a', str, int),
        ('c', lambda v: 2 * v, lambda v: v / 2),
    ]
    config = DictSource(data, converters=converter_list)

    config.a = '1'
    config.b.c = 4

    assert config._data == data
예제 #19
0
def test_stacked_setdefault():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'x': 6, 'b': {'y': 7}})
    config = StackedConfig(source1, source2)

    assert config.setdefault('a', 10) == 1
    assert config.setdefault('nonexisting', 10) == 10
    assert config.nonexisting == 10
    assert 'nonexisting' in source2

    assert config.b.setdefault('nonexisting', 20) == 20
    assert config.b.nonexisting == 20
    assert 'nonexisting' in source2.b
예제 #20
0
def test_prevent_writing_to_locked_source():
    data = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
    config = DictSource(data, readonly=True)

    with pytest.raises(TypeError) as exc_info:
        config.a = 10

    assert 'locked' in str(exc_info.value)

    with pytest.raises(TypeError) as exc_info:
        config.b.c = 20

    assert 'locked' in str(exc_info.value)
예제 #21
0
def test_stacked_dump():
    config = StackedConfig(DictSource({
        'a': 1,
        'b': {
            'c': 2
        }
    }), DictSource({'a': '10'}), DictSource({
        'x': 6,
        'b': {
            'y': 7
        }
    }))

    assert config.dump() == {'a': '10', 'b': {'c': 2, 'y': 7}, 'x': 6}
예제 #22
0
def test_write_dict_source():
    data = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
    config = DictSource(data)

    assert config.a == 1
    assert config.b.c == 2
    assert config.b.d == {'e': 3}

    config.a = 10
    config.b.c = 20
    del config.b.d.e

    assert config.a == 10
    assert config.b.c == 20
    with pytest.raises(AttributeError):
        config.b.d.e
예제 #23
0
def test_expose_sources_for_manipulation():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'a': 10, 'b': {'c': 20}})
    source3 = DictSource({'x': 6, 'b': {'y': 7}})
    config = StackedConfig()

    assert config.dump() == {}

    config.source_list.append(source1)
    assert config == source1

    config.source_list.append(source2)
    assert config == source2

    config.source_list.insert(0, source3)
    assert config.dump() == {'a': 10, 'b': {'c': 20, 'y': 7}, 'x': 6}
예제 #24
0
def test_set_missing_key_to_default_value():
    config = DictSource(auto_subsection=True)

    config.a.b = 1
    config['x'].y = 2

    assert config.a.b == 1
    assert config.x.y == 2
예제 #25
0
def test_stacked_len():
    config = StackedConfig(DictSource({
        'a': 1,
        'b': {
            'c': 2
        }
    }), DictSource({
        'x': 6,
        'b': {
            'y': 7,
            'd': {
                'e': 8
            }
        }
    }))

    assert len(config) == 3
예제 #26
0
def test_write_stacked_source_fails(key, message):
    source1 = DictSource({'a': 1, 'b': {'c': 2}}, readonly=True)
    config = StackedConfig(source1)

    with pytest.raises(TypeError) as exc_info:
        config[key] = 10

    assert message in str(exc_info.value)
예제 #27
0
def test_prevent_changes_to_source_of_subconfig():
    source1 = DictSource({'a': 1, 'b': {'c': 2}})
    source2 = DictSource({'m': 10, 'b': {'o': 20}})
    updated = DictSource({'x': 100, 'b': {'y': 200}})

    sources = SourceList(source1, source2, keychain=['b'])

    with pytest.raises(TypeError) as exc_info:
        sources.append(updated)
    assert 'cannot be mutated' in str(exc_info.value)

    with pytest.raises(TypeError) as exc_info:
        sources.insert(0, updated)
    assert 'cannot be mutated' in str(exc_info.value)

    with pytest.raises(TypeError) as exc_info:
        sources[0] = updated
    assert 'cannot be mutated' in str(exc_info.value)
예제 #28
0
def test_source_values():
    config = StackedConfig(DictSource({
        'a': 1,
        'b': {
            'c': 2
        }
    }), DictSource({
        'x': 6,
        'b': {
            'y': 7,
            'd': {
                'e': 8
            }
        }
    }))

    values = list(config.b.values())
    assert values == [2, config.b.d, 7]
예제 #29
0
def test_source_keys():
    config = StackedConfig(DictSource({
        'a': 1,
        'b': {
            'c': 2
        }
    }), DictSource({
        'x': 6,
        'b': {
            'y': 7,
            'd': {
                'e': 8
            }
        }
    }))

    keys = list(config.b.keys())
    assert keys == ['c', 'd', 'y']
예제 #30
0
def test_set_keychain():
    config = StackedConfig(DictSource({'a': {
        'b': {
            'c': 2
        }
    }}),
                           keychain=('a', 'b'))

    assert config.dump() == {'c': 2}