1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
from typing import Annotated
import pytest
from cyclopts import Argument, Group, Parameter, Token
from cyclopts.argument import ArgumentCollection
from cyclopts.exceptions import ValidationError
from cyclopts.validators import LimitedChoice
@pytest.fixture
def argument_collection_0():
return ArgumentCollection(
[
Argument(parameter=Parameter(name="--foo")),
Argument(parameter=Parameter(name="--bar")),
Argument(parameter=Parameter(name="--baz")),
]
)
@pytest.fixture
def argument_collection_1():
return ArgumentCollection(
[
Argument(
tokens=[Token(keyword="--foo", value="100", source="test")],
parameter=Parameter(name="--foo"),
value=100,
),
Argument(parameter=Parameter(name="--bar")),
Argument(parameter=Parameter(name="--baz")),
]
)
@pytest.fixture
def argument_collection_2():
return ArgumentCollection(
[
Argument(
tokens=[Token(keyword="--foo", value="100", source="test")],
parameter=Parameter(name="--foo"),
value=100,
),
Argument(
tokens=[Token(keyword="--bar", value="200", source="test")],
parameter=Parameter(name="--bar"),
value=200,
),
Argument(parameter=Parameter(name="--baz")),
]
)
@pytest.fixture
def argument_collection_3():
return ArgumentCollection(
[
Argument(
tokens=[Token(keyword="--foo", value="100", source="test")],
parameter=Parameter(name="--foo"),
value=100,
),
Argument(
tokens=[Token(keyword="--bar", value="200", source="test")],
parameter=Parameter(name="--bar"),
value=200,
),
Argument(
tokens=[Token(keyword="--baz", value="300", source="test")],
parameter=Parameter(name="--baz"),
value=300,
),
]
)
def test_limited_choice_default_success(argument_collection_0, argument_collection_1):
"""Mutually-exclusive functionality."""
validator = LimitedChoice()
validator(argument_collection_0)
validator(argument_collection_1)
@pytest.mark.parametrize("min", [None, 1])
def test_limited_choice_default_failure(min, argument_collection_2):
"""Mutually-exclusive functionality."""
if min is None:
validator = LimitedChoice()
else:
validator = LimitedChoice(min)
validator = LimitedChoice()
with pytest.raises(ValueError):
validator(argument_collection_2)
def test_limited_choice_default_min_max(
argument_collection_0, argument_collection_1, argument_collection_2, argument_collection_3
):
validator = LimitedChoice(1, 2)
with pytest.raises(ValueError):
validator(argument_collection_0)
validator(argument_collection_1)
validator(argument_collection_2)
with pytest.raises(ValueError):
validator(argument_collection_3)
def test_limited_choice_invalid_min_max():
with pytest.raises(ValueError):
LimitedChoice(2, 1)
def test_bind_group_validator_limited_choice(app):
@app.command
def foo(
*,
car: Annotated[bool, Parameter(group=Group("Vehicle", validator=LimitedChoice()))] = False,
motorcycle: Annotated[bool, Parameter(group="Vehicle")] = False,
):
pass
with pytest.raises(ValidationError) as e:
app("foo --car --motorcycle", exit_on_error=False)
assert str(e.value) == 'Invalid values for group "Vehicle". Mutually exclusive arguments: {--car, --motorcycle}'
app("foo")
app("foo --car")
app("foo --motorcycle")
def test_bind_group_validator_limited_choice_name_override(app):
@app.command
def foo(
*,
car: Annotated[bool, Parameter(group=Group("Vehicle", validator=LimitedChoice()))] = False,
motorcycle: Annotated[bool, Parameter(name="--bike", group="Vehicle")] = False,
):
pass
with pytest.raises(ValidationError) as e:
app("foo --car --bike", exit_on_error=False)
assert str(e.value) == 'Invalid values for group "Vehicle". Mutually exclusive arguments: {--car, --bike}'
|