示例#1
0
def test_config_option_default():
    class Config(config.Config):
        # Implicit default=None
        a = config.option(int, help="")
        # Default of correct type
        b = config.option(int, default=1, help="")
        # Default is function returning correct type
        c = config.option(int, default=lambda: 2, help="")

    c = config.structure({}, Config)
    assert c.a is None
    assert c.b == 1
    assert c.c == 2

    class BadDefault(config.Config):
        a = config.option(int, default="blah", help="")
        b = config.option(int, default=lambda: "blah", help="")

    with pytest.raises(config.ConfigError):
        config.structure(
            {
                # Set b, so only a's default is tested
                "b": 3,
            },
            BadDefault)

    with pytest.raises(config.ConfigError):
        config.structure(
            {
                # Set a, so only b's default is tested
                "a": 3,
            },
            BadDefault)
示例#2
0
def test_config_nested():
    class Inner(config.Config):
        x = config.option(int, default=1, help="")
        y = config.option(int, default=2, help="")

    class Config(config.Config):
        a = config.option(Inner, help="")
        b = config.option(Inner, default=Inner, help="")
        c = config.option(Inner,
                          default=lambda: Inner(dict(x=3, y=4)),
                          help="")

    # Check all default values
    c1 = config.structure({}, Config)
    assert c1.a is None
    assert c1.b.x == 1
    assert c1.b.y == 2
    assert c1.c.x == 3
    assert c1.c.y == 4

    # Check structuring from unstructured data
    c2 = config.structure({
        "a": {
            "x": 10
        },
    }, Config)
    assert isinstance(c2.a, Inner)
    assert c2.a.x == 10
    assert c2.a.y == 2
示例#3
0
def test_config_option_implicitly_required():
    """Check that a non-None default value forces the field to be required."""
    class Config(config.Config):
        a = config.option(int, default=12, help="")

    c = config.structure({}, Config)
    assert c.a == 12

    with pytest.raises(config.ConfigError):
        config.structure({"a": None}, Config)
示例#4
0
def test_config_option_required_example():
    """Check behaviour of ``required=True`` with an example value (but no default)."""
    class Config(config.Config):
        a = config.option(int, required=True, example=12, help="")

    with pytest.raises(config.ConfigError):
        config.structure({}, Config)

    c = config.make_example(Config)
    assert c.a == 12
示例#5
0
def test_config_option_map():
    default_map = {
        "x": 1,
        "y": 2,
    }

    class Config(config.Config):
        a = config.option_map(int, help="")
        b = config.option_map(int, default=default_map, help="")
        c = config.option_map(int, default=lambda: {"y": 3, "z": 4}, help="")

    # Check all default values
    c1 = config.structure({}, Config)
    assert c1.a == {}
    assert c1.b == {"x": 1, "y": 2}
    assert c1.c == {"y": 3, "z": 4}

    # Avoid pitfall of mutable default values
    default_map["x"] = 20
    assert c1.b == {"x": 1, "y": 2}

    # Check supplied values
    c2 = config.structure(
        {
            "a": {
                "n": -1,
                "m": -2
            },
            "b": {},
            "c": {
                "i": 0,
                "j": -1
            },
        }, Config)
    assert c2.a == {"n": -1, "m": -2}
    assert c2.b == {}
    assert c2.c == {"i": 0, "j": -1}

    # Check the type of keys is enforced
    c3 = config.structure({
        "a": {
            (1, 2): 2
        },
    }, Config)
    assert c3.a == {"(1, 2)": 2}

    # Check the type of values
    with pytest.raises(config.ConfigError):
        config.structure({
            "a": {
                "x": None
            },
        }, Config)
示例#6
0
def test_config_option_required_default():
    """Check behaviour of ``required=True`` with a default value."""
    class Config(config.Config):
        a = config.option(int, required=True, default=12, help="")

    c = config.structure({}, Config)
    assert c.a == 12

    c = config.structure({"a": 23}, Config)
    assert c.a == 23

    with pytest.raises(config.ConfigError):
        config.structure({"a": None}, Config)
示例#7
0
def test_config_option_wordlist():
    class Config(config.Config):
        a = config.option(config.WordList, help="")
        b = config.option(config.WordList, help="")
        c = config.option(config.WordList, default="foo bar baz", help="")
        d = config.option(config.WordList, default=["ab", "cd", "ef"], help="")
        e = config.option_list(config.WordList, help="")
        f = config.option_map(config.WordList, help="")

    c = config.structure(
        {
            "a": "foo bar baz",
            "b": ["ab", "cd", "ef"],
            "e": ["foo bar baz", ["ab", "cd", "ef"]],
            "f": {
                "x": "foo bar baz",
                "y": ["ab", "cd", "ef"]
            },
        }, Config)
    assert c.a == ["foo", "bar", "baz"]
    assert c.b == ["ab", "cd", "ef"]
    assert c.c == ["foo", "bar", "baz"]
    assert c.d == ["ab", "cd", "ef"]
    assert c.e == [["foo", "bar", "baz"], ["ab", "cd", "ef"]]
    assert c.f == {"x": ["foo", "bar", "baz"], "y": ["ab", "cd", "ef"]}
示例#8
0
def test_config_option_not_required_default():
    """Check that ``required=False`` overrides the "implicitly required" behaviour of having a default."""
    class Config(config.Config):
        a = config.option(int, default=12, required=False, help="")

    c = config.structure({"a": None}, Config)
    assert c.a is None
示例#9
0
def test_config_option_not_required_no_default():
    """Check that default value of None is the default behaviour."""
    class Config(config.Config):
        a = config.option(int, help="")

    c = config.structure({}, Config)
    assert c.a is None
示例#10
0
def test_config_nested_list():
    class Inner(config.Config):
        x = config.option(int, default=1, help="")
        y = config.option(int, default=2, help="")

    class Config(config.Config):
        a = config.option_list(Inner, help="")

    # Check default value
    c1 = config.structure({}, Config)
    assert c1.a == []

    # Check structuring from unstructured data
    c2 = config.structure(
        {
            "a": [
                {
                    "x": 10,
                    "y": 20
                },
                {
                    "x": 11,
                    "y": 21
                },
                {
                    "x": 12,
                    "y": 22
                },
            ],
        }, Config)
    assert all(isinstance(o, Inner) for o in c2.a)
    assert c2.a[0].x == 10
    assert c2.a[0].y == 20
    assert c2.a[1].x == 11
    assert c2.a[1].y == 21
    assert c2.a[2].x == 12
    assert c2.a[2].y == 22

    # Check type enforcement
    with pytest.raises(config.ConfigError):
        config.structure({
            "a": [
                {
                    "x": None
                },
            ],
        }, Config)
示例#11
0
def test_config_option_env():
    class Config(config.Config):
        a = config.option(str, env=["A_PRIMARY", "A_FALLBACK"], help="")
        b = config.option(int, env=["B_ENV"], help="")
        c = config.option(bool, env="C_ENV", help="")

    c1 = config.structure({}, Config)
    assert c1.a is None
    assert c1.b is None

    # Environment variable precedence
    with TempEnvVars({"A_PRIMARY": "foo", "A_FALLBACK": "bar"}):
        c2 = config.structure({}, Config)
        assert c2.a == "foo"
    with TempEnvVars({"A_FALLBACK": "bar"}):
        c3 = config.structure({}, Config)
        assert c3.a == "bar"

    # Type conversion: int
    with TempEnvVars({"B_ENV": "2"}):
        c4 = config.structure({}, Config)
        assert c4.b == 2

    # Type conversion: bool
    with TempEnvVars({"C_ENV": "true"}):
        c5 = config.structure({}, Config)
        assert c5.c is True
    with TempEnvVars({"C_ENV": "false"}):
        c5 = config.structure({}, Config)
        assert c5.c is False

    # Supplied value causes environment variable to be ignored
    with TempEnvVars({"C_ENV": "false"}):
        c5 = config.structure({"c": True}, Config)
        assert c5.c is True
示例#12
0
def test_config_nested_map():
    class Inner(config.Config):
        x = config.option(int, default=1, help="")
        y = config.option(int, default=2, help="")

    class Config(config.Config):
        a = config.option_map(Inner, help="")

    # Check default value
    c1 = config.structure({}, Config)
    assert c1.a == {}

    # Check structuring from unstructured data
    c2 = config.structure(
        {
            "a": {
                "b": {
                    "x": 10,
                    "y": 20
                },
                "c": {
                    "x": 11,
                    "y": 21
                },
            },
        }, Config)
    assert all(isinstance(v, Inner) for v in c2.a.values())
    assert c2.a["b"].x == 10
    assert c2.a["b"].y == 20
    assert c2.a["c"].x == 11
    assert c2.a["c"].y == 21

    # Check type enforcement
    with pytest.raises(config.ConfigError):
        config.structure({
            "a": {
                "b": {
                    "x": None
                },
            },
        }, Config)
示例#13
0
def test_config_option_validate():
    class Config(config.Config):
        # Option with default=None (or omitted) can be None
        a = config.option(int, help="")
        # Option without default=None must not be None
        b = config.option(int, default=1, help="")

    # Both have correctly typed values
    c1 = config.structure({
        "a": 3,
        "b": 4,
    }, Config)
    assert c1.a == 3
    assert c1.b == 4

    # None value where default=None is allowed
    c2 = config.structure({
        "a": None,
    }, Config)
    assert c2.a is None

    # (But incorrect type is not allowed)
    with pytest.raises(config.ConfigError):
        config.structure({
            "a": "blah",
        }, Config)

    # None value where default!=None is not allowed
    with pytest.raises(config.ConfigError):
        config.structure({
            "b": None,
        }, Config)
示例#14
0
def test_config_option_list():
    default_list = [1, 2, 3]

    class Config(config.Config):
        a = config.option_list(int, help="")
        b = config.option_list(int, default=default_list, help="")
        c = config.option_list(int, default=lambda: [4, 5, 6], help="")

    # Check all default values
    c1 = config.structure({}, Config)
    assert c1.a == []
    assert c1.b == [1, 2, 3]
    assert c1.c == [4, 5, 6]

    # Avoid pitfall of mutable default values
    default_list[1] = 20
    assert c1.b == [1, 2, 3]

    # Check supplied values
    c2 = config.structure({
        "a": [9, 8],
        "b": [],
        "c": [7, 6, 5],
    }, Config)
    assert c2.a == [9, 8]
    assert c2.b == []
    assert c2.c == [7, 6, 5]

    # Check other sequences are read as lists
    c3 = config.structure({
        "a": (10, 11),
    }, Config)
    assert c3.a == [10, 11]

    # Check the type of sequence values
    with pytest.raises(config.ConfigError):
        config.structure({
            "a": [1, None],
        }, Config)