Add support for new select selector properties (#68952)
* Add support for new select selector properties * fix mode option * Apply suggestions from code review * Correct validation for empty options, update tests Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
9432ab07c2
commit
6b2fe6cba9
2 changed files with 53 additions and 13 deletions
|
@ -471,25 +471,37 @@ select_option = vol.All(
|
||||||
|
|
||||||
@SELECTORS.register("select")
|
@SELECTORS.register("select")
|
||||||
class SelectSelector(Selector):
|
class SelectSelector(Selector):
|
||||||
"""Selector for an single-choice input select."""
|
"""Selector for an single or multi-choice input select."""
|
||||||
|
|
||||||
selector_type = "select"
|
selector_type = "select"
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required("options"): vol.All(
|
vol.Required("options"): vol.All(vol.Any([str], [select_option])),
|
||||||
vol.Any([str], [select_option]), vol.Length(min=1)
|
vol.Optional("multiple", default=False): cv.boolean,
|
||||||
)
|
vol.Optional("custom_value", default=False): cv.boolean,
|
||||||
|
vol.Optional("mode"): vol.In(("list", "dropdown")),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, data: Any) -> Any:
|
def __call__(self, data: Any) -> Any:
|
||||||
"""Validate the passed selection."""
|
"""Validate the passed selection."""
|
||||||
if isinstance(self.config["options"][0], str):
|
options = []
|
||||||
options = self.config["options"]
|
if self.config["options"]:
|
||||||
else:
|
if isinstance(self.config["options"][0], str):
|
||||||
options = [option["value"] for option in self.config["options"]]
|
options = self.config["options"]
|
||||||
return vol.In(options)(vol.Schema(str)(data))
|
else:
|
||||||
|
options = [option["value"] for option in self.config["options"]]
|
||||||
|
|
||||||
|
parent_schema = vol.In(options)
|
||||||
|
if self.config["custom_value"]:
|
||||||
|
parent_schema = vol.Any(parent_schema, str)
|
||||||
|
|
||||||
|
if not self.config["multiple"]:
|
||||||
|
return parent_schema(vol.Schema(str)(data))
|
||||||
|
if not isinstance(data, list):
|
||||||
|
raise vol.Invalid("Value should be a list")
|
||||||
|
return [parent_schema(vol.Schema(str)(val)) for val in data]
|
||||||
|
|
||||||
|
|
||||||
@SELECTORS.register("text")
|
@SELECTORS.register("text")
|
||||||
|
|
|
@ -246,7 +246,7 @@ def test_number_selector_schema(schema, valid_selections, invalid_selections):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_number_selector_schema_error(schema):
|
def test_number_selector_schema_error(schema):
|
||||||
"""Test select selector."""
|
"""Test number selector."""
|
||||||
with pytest.raises(vol.Invalid):
|
with pytest.raises(vol.Invalid):
|
||||||
selector.validate_selector({"number": schema})
|
selector.validate_selector({"number": schema})
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ def test_text_selector_schema(schema, valid_selections, invalid_selections):
|
||||||
(
|
(
|
||||||
{"options": ["red", "green", "blue"]},
|
{"options": ["red", "green", "blue"]},
|
||||||
("red", "green", "blue"),
|
("red", "green", "blue"),
|
||||||
("cat", 0, None),
|
("cat", 0, None, ["red"]),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -359,7 +359,36 @@ def test_text_selector_schema(schema, valid_selections, invalid_selections):
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
("red", "green"),
|
("red", "green"),
|
||||||
("cat", 0, None),
|
("cat", 0, None, ["red"]),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"options": ["red", "green", "blue"], "multiple": True},
|
||||||
|
(["red"], ["green", "blue"], []),
|
||||||
|
("cat", 0, None, "red"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"options": ["red", "green", "blue"],
|
||||||
|
"multiple": True,
|
||||||
|
"custom_value": True,
|
||||||
|
},
|
||||||
|
(["red"], ["green", "blue"], ["red", "cat"], []),
|
||||||
|
("cat", 0, None, "red"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"options": ["red", "green", "blue"], "custom_value": True},
|
||||||
|
("red", "green", "blue", "cat"),
|
||||||
|
(0, None, ["red"]),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"options": [], "custom_value": True},
|
||||||
|
("red", "cat"),
|
||||||
|
(0, None, ["red"]),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"options": [], "custom_value": True, "multiple": True},
|
||||||
|
(["red"], ["green", "blue"], []),
|
||||||
|
(0, None, "red"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -373,7 +402,6 @@ def test_select_selector_schema(schema, valid_selections, invalid_selections):
|
||||||
(
|
(
|
||||||
{}, # Must have options
|
{}, # Must have options
|
||||||
{"options": {"hello": "World"}}, # Options must be a list
|
{"options": {"hello": "World"}}, # Options must be a list
|
||||||
{"options": []}, # Must have at least option
|
|
||||||
# Options must be strings or value / label pairs
|
# Options must be strings or value / label pairs
|
||||||
{"options": [{"hello": "World"}]},
|
{"options": [{"hello": "World"}]},
|
||||||
# Options must all be of the same type
|
# Options must all be of the same type
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue