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:
Raman Gupta 2022-03-31 05:28:49 -04:00 committed by GitHub
parent 9432ab07c2
commit 6b2fe6cba9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 13 deletions

View file

@ -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."""
options = []
if self.config["options"]:
if isinstance(self.config["options"][0], str): if isinstance(self.config["options"][0], str):
options = self.config["options"] options = self.config["options"]
else: else:
options = [option["value"] for option in self.config["options"]] options = [option["value"] for option in self.config["options"]]
return vol.In(options)(vol.Schema(str)(data))
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")

View file

@ -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