mirror of
https://github.com/esphome/esphome.git
synced 2025-09-01 19:02:18 +01:00
add-black (#1593)
* Add black Update pre commit Update pre commit add empty line * Format with black
This commit is contained in:
committed by
GitHub
parent
2b60b0f1fa
commit
69879920eb
@@ -27,4 +27,3 @@ def fixture_path() -> Path:
|
||||
Location of all fixture files.
|
||||
"""
|
||||
return here / "fixtures"
|
||||
|
||||
|
@@ -12,4 +12,6 @@ def mac_addr_strings():
|
||||
This consists of six strings representing integers [0..255],
|
||||
without zero-padding, joined by dots.
|
||||
"""
|
||||
return st.builds("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}".format, *(6 * [st.integers(0, 255)]))
|
||||
return st.builds(
|
||||
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}".format, *(6 * [st.integers(0, 255)])
|
||||
)
|
||||
|
@@ -4,23 +4,75 @@ from esphome import codegen as cg
|
||||
|
||||
|
||||
# Test interface remains the same.
|
||||
@pytest.mark.parametrize("attr", (
|
||||
# from cpp_generator
|
||||
"Expression", "RawExpression", "RawStatement", "TemplateArguments",
|
||||
"StructInitializer", "ArrayInitializer", "safe_exp", "Statement", "LineComment",
|
||||
"progmem_array", "statement", "variable", "Pvariable", "new_Pvariable",
|
||||
"add", "add_global", "add_library", "add_build_flag", "add_define",
|
||||
"get_variable", "get_variable_with_full_id", "process_lambda", "is_template", "templatable", "MockObj",
|
||||
"MockObjClass",
|
||||
# from cpp_helpers
|
||||
"gpio_pin_expression", "register_component", "build_registry_entry",
|
||||
"build_registry_list", "extract_registry_entry_config", "register_parented",
|
||||
"global_ns", "void", "nullptr", "float_", "double", "bool_", "int_", "std_ns", "std_string",
|
||||
"std_vector", "uint8", "uint16", "uint32", "int32", "const_char_ptr", "NAN",
|
||||
"esphome_ns", "App", "Nameable", "Component", "ComponentPtr",
|
||||
# from cpp_types
|
||||
"PollingComponent", "Application", "optional", "arduino_json_ns", "JsonObject",
|
||||
"JsonObjectRef", "JsonObjectConstRef", "Controller", "GPIOPin"
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"attr",
|
||||
(
|
||||
# from cpp_generator
|
||||
"Expression",
|
||||
"RawExpression",
|
||||
"RawStatement",
|
||||
"TemplateArguments",
|
||||
"StructInitializer",
|
||||
"ArrayInitializer",
|
||||
"safe_exp",
|
||||
"Statement",
|
||||
"LineComment",
|
||||
"progmem_array",
|
||||
"statement",
|
||||
"variable",
|
||||
"Pvariable",
|
||||
"new_Pvariable",
|
||||
"add",
|
||||
"add_global",
|
||||
"add_library",
|
||||
"add_build_flag",
|
||||
"add_define",
|
||||
"get_variable",
|
||||
"get_variable_with_full_id",
|
||||
"process_lambda",
|
||||
"is_template",
|
||||
"templatable",
|
||||
"MockObj",
|
||||
"MockObjClass",
|
||||
# from cpp_helpers
|
||||
"gpio_pin_expression",
|
||||
"register_component",
|
||||
"build_registry_entry",
|
||||
"build_registry_list",
|
||||
"extract_registry_entry_config",
|
||||
"register_parented",
|
||||
"global_ns",
|
||||
"void",
|
||||
"nullptr",
|
||||
"float_",
|
||||
"double",
|
||||
"bool_",
|
||||
"int_",
|
||||
"std_ns",
|
||||
"std_string",
|
||||
"std_vector",
|
||||
"uint8",
|
||||
"uint16",
|
||||
"uint32",
|
||||
"int32",
|
||||
"const_char_ptr",
|
||||
"NAN",
|
||||
"esphome_ns",
|
||||
"App",
|
||||
"Nameable",
|
||||
"Component",
|
||||
"ComponentPtr",
|
||||
# from cpp_types
|
||||
"PollingComponent",
|
||||
"Application",
|
||||
"optional",
|
||||
"arduino_json_ns",
|
||||
"JsonObject",
|
||||
"JsonObjectRef",
|
||||
"JsonObjectConstRef",
|
||||
"Controller",
|
||||
"GPIOPin",
|
||||
),
|
||||
)
|
||||
def test_exists(attr):
|
||||
assert hasattr(cg, attr)
|
||||
|
@@ -2,7 +2,7 @@ import pytest
|
||||
import string
|
||||
|
||||
from hypothesis import given, example
|
||||
from hypothesis.strategies import one_of, text, integers, booleans, builds
|
||||
from hypothesis.strategies import one_of, text, integers, builds
|
||||
|
||||
from esphome import config_validation
|
||||
from esphome.config_validation import Invalid
|
||||
@@ -24,7 +24,7 @@ def test_alphanumeric__valid(value):
|
||||
@pytest.mark.parametrize("value", ("£23", "Foo!"))
|
||||
def test_alphanumeric__invalid(value):
|
||||
with pytest.raises(Invalid):
|
||||
actual = config_validation.alphanumeric(value)
|
||||
config_validation.alphanumeric(value)
|
||||
|
||||
|
||||
@given(value=text(alphabet=string.ascii_lowercase + string.digits + "_-"))
|
||||
@@ -34,9 +34,7 @@ def test_valid_name__valid(value):
|
||||
assert actual == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
"foo bar", "FooBar", "foo::bar"
|
||||
))
|
||||
@pytest.mark.parametrize("value", ("foo bar", "FooBar", "foo::bar"))
|
||||
def test_valid_name__invalid(value):
|
||||
with pytest.raises(Invalid):
|
||||
config_validation.valid_name(value)
|
||||
@@ -49,9 +47,7 @@ def test_string__valid(value):
|
||||
assert actual == str(value)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
{}, [], True, False, None
|
||||
))
|
||||
@pytest.mark.parametrize("value", ({}, [], True, False, None))
|
||||
def test_string__invalid(value):
|
||||
with pytest.raises(Invalid):
|
||||
config_validation.string(value)
|
||||
@@ -83,23 +79,17 @@ def test_icon__invalid():
|
||||
config_validation.icon("foo")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
"True", "YES", "on", "enAblE", True
|
||||
))
|
||||
@pytest.mark.parametrize("value", ("True", "YES", "on", "enAblE", True))
|
||||
def test_boolean__valid_true(value):
|
||||
assert config_validation.boolean(value) is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
"False", "NO", "off", "disAblE", False
|
||||
))
|
||||
@pytest.mark.parametrize("value", ("False", "NO", "off", "disAblE", False))
|
||||
def test_boolean__valid_false(value):
|
||||
assert config_validation.boolean(value) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
None, 1, 0, "foo"
|
||||
))
|
||||
@pytest.mark.parametrize("value", (None, 1, 0, "foo"))
|
||||
def test_boolean__invalid(value):
|
||||
with pytest.raises(Invalid, match="Expected boolean value"):
|
||||
config_validation.boolean(value)
|
||||
|
@@ -8,13 +8,16 @@ from esphome import core, const
|
||||
|
||||
|
||||
class TestHexInt:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
(1, "0x01"),
|
||||
(255, "0xFF"),
|
||||
(128, "0x80"),
|
||||
(256, "0x100"),
|
||||
(-1, "-0x01"), # TODO: this currently fails
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
(1, "0x01"),
|
||||
(255, "0xFF"),
|
||||
(128, "0x80"),
|
||||
(256, "0x100"),
|
||||
(-1, "-0x01"), # TODO: this currently fails
|
||||
),
|
||||
)
|
||||
def test_str(self, value, expected):
|
||||
target = core.HexInt(value)
|
||||
|
||||
@@ -68,18 +71,14 @@ class TestMACAddress:
|
||||
assert actual.text == "0xDEADBEEF00FFULL"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
1, 2, -1, 0, 1.0, -1.0, 42.0009, -42.0009
|
||||
))
|
||||
@pytest.mark.parametrize("value", (1, 2, -1, 0, 1.0, -1.0, 42.0009, -42.0009))
|
||||
def test_is_approximately_integer__in_range(value):
|
||||
actual = core.is_approximately_integer(value)
|
||||
|
||||
assert actual is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
42.01, -42.01, 1.5
|
||||
))
|
||||
@pytest.mark.parametrize("value", (42.01, -42.01, 1.5))
|
||||
def test_is_approximately_integer__not_in_range(value):
|
||||
actual = core.is_approximately_integer(value)
|
||||
|
||||
@@ -87,26 +86,29 @@ def test_is_approximately_integer__not_in_range(value):
|
||||
|
||||
|
||||
class TestTimePeriod:
|
||||
@pytest.mark.parametrize("kwargs, expected", (
|
||||
({}, {}),
|
||||
({"microseconds": 1}, {"microseconds": 1}),
|
||||
({"microseconds": 1.0001}, {"microseconds": 1}),
|
||||
({"milliseconds": 2}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.0001}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.01}, {"milliseconds": 2, "microseconds": 10}),
|
||||
({"seconds": 3}, {"seconds": 3}),
|
||||
({"seconds": 3.0001}, {"seconds": 3}),
|
||||
({"seconds": 3.01}, {"seconds": 3, "milliseconds": 10}),
|
||||
({"minutes": 4}, {"minutes": 4}),
|
||||
({"minutes": 4.0001}, {"minutes": 4}),
|
||||
({"minutes": 4.1}, {"minutes": 4, "seconds": 6}),
|
||||
({"hours": 5}, {"hours": 5}),
|
||||
({"hours": 5.0001}, {"hours": 5}),
|
||||
({"hours": 5.1}, {"hours": 5, "minutes": 6}),
|
||||
({"days": 6}, {"days": 6}),
|
||||
({"days": 6.0001}, {"days": 6}),
|
||||
({"days": 6.1}, {"days": 6, "hours": 2, "minutes": 24}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"kwargs, expected",
|
||||
(
|
||||
({}, {}),
|
||||
({"microseconds": 1}, {"microseconds": 1}),
|
||||
({"microseconds": 1.0001}, {"microseconds": 1}),
|
||||
({"milliseconds": 2}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.0001}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.01}, {"milliseconds": 2, "microseconds": 10}),
|
||||
({"seconds": 3}, {"seconds": 3}),
|
||||
({"seconds": 3.0001}, {"seconds": 3}),
|
||||
({"seconds": 3.01}, {"seconds": 3, "milliseconds": 10}),
|
||||
({"minutes": 4}, {"minutes": 4}),
|
||||
({"minutes": 4.0001}, {"minutes": 4}),
|
||||
({"minutes": 4.1}, {"minutes": 4, "seconds": 6}),
|
||||
({"hours": 5}, {"hours": 5}),
|
||||
({"hours": 5.0001}, {"hours": 5}),
|
||||
({"hours": 5.1}, {"hours": 5, "minutes": 6}),
|
||||
({"days": 6}, {"days": 6}),
|
||||
({"days": 6.0001}, {"days": 6}),
|
||||
({"days": 6.1}, {"days": 6, "hours": 2, "minutes": 24}),
|
||||
),
|
||||
)
|
||||
def test_init(self, kwargs, expected):
|
||||
target = core.TimePeriod(**kwargs)
|
||||
|
||||
@@ -118,26 +120,29 @@ class TestTimePeriod:
|
||||
with pytest.raises(ValueError, match="Maximum precision is microseconds"):
|
||||
core.TimePeriod(microseconds=1.1)
|
||||
|
||||
@pytest.mark.parametrize("kwargs, expected", (
|
||||
({}, "0s"),
|
||||
({"microseconds": 1}, "1us"),
|
||||
({"microseconds": 1.0001}, "1us"),
|
||||
({"milliseconds": 2}, "2ms"),
|
||||
({"milliseconds": 2.0001}, "2ms"),
|
||||
({"milliseconds": 2.01}, "2010us"),
|
||||
({"seconds": 3}, "3s"),
|
||||
({"seconds": 3.0001}, "3s"),
|
||||
({"seconds": 3.01}, "3010ms"),
|
||||
({"minutes": 4}, "4min"),
|
||||
({"minutes": 4.0001}, "4min"),
|
||||
({"minutes": 4.1}, "246s"),
|
||||
({"hours": 5}, "5h"),
|
||||
({"hours": 5.0001}, "5h"),
|
||||
({"hours": 5.1}, "306min"),
|
||||
({"days": 6}, "6d"),
|
||||
({"days": 6.0001}, "6d"),
|
||||
({"days": 6.1}, "8784min"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"kwargs, expected",
|
||||
(
|
||||
({}, "0s"),
|
||||
({"microseconds": 1}, "1us"),
|
||||
({"microseconds": 1.0001}, "1us"),
|
||||
({"milliseconds": 2}, "2ms"),
|
||||
({"milliseconds": 2.0001}, "2ms"),
|
||||
({"milliseconds": 2.01}, "2010us"),
|
||||
({"seconds": 3}, "3s"),
|
||||
({"seconds": 3.0001}, "3s"),
|
||||
({"seconds": 3.01}, "3010ms"),
|
||||
({"minutes": 4}, "4min"),
|
||||
({"minutes": 4.0001}, "4min"),
|
||||
({"minutes": 4.1}, "246s"),
|
||||
({"hours": 5}, "5h"),
|
||||
({"hours": 5.0001}, "5h"),
|
||||
({"hours": 5.1}, "306min"),
|
||||
({"days": 6}, "6d"),
|
||||
({"days": 6.0001}, "6d"),
|
||||
({"days": 6.1}, "8784min"),
|
||||
),
|
||||
)
|
||||
def test_str(self, kwargs, expected):
|
||||
target = core.TimePeriod(**kwargs)
|
||||
|
||||
@@ -145,61 +150,59 @@ class TestTimePeriod:
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.TimePeriod(microseconds=900), False),
|
||||
("__eq__", core.TimePeriod(milliseconds=1), True),
|
||||
("__eq__", core.TimePeriod(microseconds=1100), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
|
||||
("__ne__", core.TimePeriod(microseconds=900), True),
|
||||
("__ne__", core.TimePeriod(milliseconds=1), False),
|
||||
("__ne__", core.TimePeriod(microseconds=1100), True),
|
||||
("__ne__", 1000, NotImplemented),
|
||||
("__ne__", "1000", NotImplemented),
|
||||
("__ne__", True, NotImplemented),
|
||||
("__ne__", object(), NotImplemented),
|
||||
("__ne__", None, NotImplemented),
|
||||
|
||||
("__lt__", core.TimePeriod(microseconds=900), False),
|
||||
("__lt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__lt__", core.TimePeriod(microseconds=1100), True),
|
||||
("__lt__", 1000, NotImplemented),
|
||||
("__lt__", "1000", NotImplemented),
|
||||
("__lt__", True, NotImplemented),
|
||||
("__lt__", object(), NotImplemented),
|
||||
("__lt__", None, NotImplemented),
|
||||
|
||||
("__gt__", core.TimePeriod(microseconds=900), True),
|
||||
("__gt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__gt__", core.TimePeriod(microseconds=1100), False),
|
||||
("__gt__", 1000, NotImplemented),
|
||||
("__gt__", "1000", NotImplemented),
|
||||
("__gt__", True, NotImplemented),
|
||||
("__gt__", object(), NotImplemented),
|
||||
("__gt__", None, NotImplemented),
|
||||
|
||||
("__le__", core.TimePeriod(microseconds=900), False),
|
||||
("__le__", core.TimePeriod(milliseconds=1), True),
|
||||
("__le__", core.TimePeriod(microseconds=1100), True),
|
||||
("__le__", 1000, NotImplemented),
|
||||
("__le__", "1000", NotImplemented),
|
||||
("__le__", True, NotImplemented),
|
||||
("__le__", object(), NotImplemented),
|
||||
("__le__", None, NotImplemented),
|
||||
|
||||
("__ge__", core.TimePeriod(microseconds=900), True),
|
||||
("__ge__", core.TimePeriod(milliseconds=1), True),
|
||||
("__ge__", core.TimePeriod(microseconds=1100), False),
|
||||
("__ge__", 1000, NotImplemented),
|
||||
("__ge__", "1000", NotImplemented),
|
||||
("__ge__", True, NotImplemented),
|
||||
("__ge__", object(), NotImplemented),
|
||||
("__ge__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.TimePeriod(microseconds=900), False),
|
||||
("__eq__", core.TimePeriod(milliseconds=1), True),
|
||||
("__eq__", core.TimePeriod(microseconds=1100), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
("__ne__", core.TimePeriod(microseconds=900), True),
|
||||
("__ne__", core.TimePeriod(milliseconds=1), False),
|
||||
("__ne__", core.TimePeriod(microseconds=1100), True),
|
||||
("__ne__", 1000, NotImplemented),
|
||||
("__ne__", "1000", NotImplemented),
|
||||
("__ne__", True, NotImplemented),
|
||||
("__ne__", object(), NotImplemented),
|
||||
("__ne__", None, NotImplemented),
|
||||
("__lt__", core.TimePeriod(microseconds=900), False),
|
||||
("__lt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__lt__", core.TimePeriod(microseconds=1100), True),
|
||||
("__lt__", 1000, NotImplemented),
|
||||
("__lt__", "1000", NotImplemented),
|
||||
("__lt__", True, NotImplemented),
|
||||
("__lt__", object(), NotImplemented),
|
||||
("__lt__", None, NotImplemented),
|
||||
("__gt__", core.TimePeriod(microseconds=900), True),
|
||||
("__gt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__gt__", core.TimePeriod(microseconds=1100), False),
|
||||
("__gt__", 1000, NotImplemented),
|
||||
("__gt__", "1000", NotImplemented),
|
||||
("__gt__", True, NotImplemented),
|
||||
("__gt__", object(), NotImplemented),
|
||||
("__gt__", None, NotImplemented),
|
||||
("__le__", core.TimePeriod(microseconds=900), False),
|
||||
("__le__", core.TimePeriod(milliseconds=1), True),
|
||||
("__le__", core.TimePeriod(microseconds=1100), True),
|
||||
("__le__", 1000, NotImplemented),
|
||||
("__le__", "1000", NotImplemented),
|
||||
("__le__", True, NotImplemented),
|
||||
("__le__", object(), NotImplemented),
|
||||
("__le__", None, NotImplemented),
|
||||
("__ge__", core.TimePeriod(microseconds=900), True),
|
||||
("__ge__", core.TimePeriod(milliseconds=1), True),
|
||||
("__ge__", core.TimePeriod(microseconds=1100), False),
|
||||
("__ge__", 1000, NotImplemented),
|
||||
("__ge__", "1000", NotImplemented),
|
||||
("__ge__", True, NotImplemented),
|
||||
("__ge__", object(), NotImplemented),
|
||||
("__ge__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.TimePeriod(microseconds=1000)
|
||||
|
||||
@@ -238,19 +241,19 @@ class TestLambda:
|
||||
"it.strftime(64, 0, ",
|
||||
"my_font",
|
||||
"",
|
||||
", TextAlign::TOP_CENTER, \"%H:%M:%S\", ",
|
||||
', TextAlign::TOP_CENTER, "%H:%M:%S", ',
|
||||
"esptime",
|
||||
".",
|
||||
"now());\nit.printf(64, 16, ",
|
||||
"my_font2",
|
||||
"",
|
||||
", TextAlign::TOP_CENTER, \"%.1f°C (%.1f%%)\", ",
|
||||
', TextAlign::TOP_CENTER, "%.1f°C (%.1f%%)", ',
|
||||
"office_tmp",
|
||||
".",
|
||||
"state, ",
|
||||
"office_hmd",
|
||||
".",
|
||||
"state);\n \nint x = 4; "
|
||||
"state);\n \nint x = 4; ",
|
||||
]
|
||||
|
||||
def test_requires_ids(self):
|
||||
@@ -296,24 +299,33 @@ class TestID:
|
||||
def target(self):
|
||||
return core.ID(None, is_declaration=True, type="binary_sensor::Example")
|
||||
|
||||
@pytest.mark.parametrize("id, is_manual, expected", (
|
||||
("foo", None, True),
|
||||
(None, None, False),
|
||||
("foo", True, True),
|
||||
("foo", False, False),
|
||||
(None, True, True),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"id, is_manual, expected",
|
||||
(
|
||||
("foo", None, True),
|
||||
(None, None, False),
|
||||
("foo", True, True),
|
||||
("foo", False, False),
|
||||
(None, True, True),
|
||||
),
|
||||
)
|
||||
def test_init__resolve_is_manual(self, id, is_manual, expected):
|
||||
target = core.ID(id, is_manual=is_manual)
|
||||
|
||||
assert target.is_manual == expected
|
||||
|
||||
@pytest.mark.parametrize("registered_ids, expected", (
|
||||
([], "binary_sensor_example"),
|
||||
(["binary_sensor_example"], "binary_sensor_example_2"),
|
||||
(["foo"], "binary_sensor_example"),
|
||||
(["binary_sensor_example", "foo", "binary_sensor_example_2"], "binary_sensor_example_3"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"registered_ids, expected",
|
||||
(
|
||||
([], "binary_sensor_example"),
|
||||
(["binary_sensor_example"], "binary_sensor_example_2"),
|
||||
(["foo"], "binary_sensor_example"),
|
||||
(
|
||||
["binary_sensor_example", "foo", "binary_sensor_example_2"],
|
||||
"binary_sensor_example_3",
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_resolve(self, target, registered_ids, expected):
|
||||
actual = target.resolve(registered_ids)
|
||||
|
||||
@@ -326,18 +338,23 @@ class TestID:
|
||||
actual = target.copy()
|
||||
|
||||
assert actual is not target
|
||||
assert all(getattr(actual, n) == getattr(target, n)
|
||||
for n in ("id", "is_declaration", "type", "is_manual"))
|
||||
assert all(
|
||||
getattr(actual, n) == getattr(target, n)
|
||||
for n in ("id", "is_declaration", "type", "is_manual")
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.ID(id="foo"), True),
|
||||
("__eq__", core.ID(id="bar"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.ID(id="foo"), True),
|
||||
("__eq__", core.ID(id="bar"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.ID(id="foo")
|
||||
|
||||
@@ -384,14 +401,17 @@ class TestDocumentRange:
|
||||
|
||||
|
||||
class TestDefine:
|
||||
@pytest.mark.parametrize("name, value, prop, expected", (
|
||||
("ANSWER", None, "as_build_flag", "-DANSWER"),
|
||||
("ANSWER", None, "as_macro", "#define ANSWER"),
|
||||
("ANSWER", None, "as_tuple", ("ANSWER", None)),
|
||||
("ANSWER", 42, "as_build_flag", "-DANSWER=42"),
|
||||
("ANSWER", 42, "as_macro", "#define ANSWER 42"),
|
||||
("ANSWER", 42, "as_tuple", ("ANSWER", 42)),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"name, value, prop, expected",
|
||||
(
|
||||
("ANSWER", None, "as_build_flag", "-DANSWER"),
|
||||
("ANSWER", None, "as_macro", "#define ANSWER"),
|
||||
("ANSWER", None, "as_tuple", ("ANSWER", None)),
|
||||
("ANSWER", 42, "as_build_flag", "-DANSWER=42"),
|
||||
("ANSWER", 42, "as_macro", "#define ANSWER 42"),
|
||||
("ANSWER", 42, "as_tuple", ("ANSWER", 42)),
|
||||
),
|
||||
)
|
||||
def test_properties(self, name, value, prop, expected):
|
||||
target = core.Define(name, value)
|
||||
|
||||
@@ -399,18 +419,21 @@ class TestDefine:
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.Define(name="FOO", value=42), True),
|
||||
("__eq__", core.Define(name="FOO", value=13), False),
|
||||
("__eq__", core.Define(name="FOO"), False),
|
||||
("__eq__", core.Define(name="BAR", value=42), False),
|
||||
("__eq__", core.Define(name="BAR"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.Define(name="FOO", value=42), True),
|
||||
("__eq__", core.Define(name="FOO", value=13), False),
|
||||
("__eq__", core.Define(name="FOO"), False),
|
||||
("__eq__", core.Define(name="BAR", value=42), False),
|
||||
("__eq__", core.Define(name="BAR"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.Define(name="FOO", value=42)
|
||||
|
||||
@@ -420,12 +443,15 @@ class TestDefine:
|
||||
|
||||
|
||||
class TestLibrary:
|
||||
@pytest.mark.parametrize("name, value, prop, expected", (
|
||||
("mylib", None, "as_lib_dep", "mylib"),
|
||||
("mylib", None, "as_tuple", ("mylib", None)),
|
||||
("mylib", "1.2.3", "as_lib_dep", "mylib@1.2.3"),
|
||||
("mylib", "1.2.3", "as_tuple", ("mylib", "1.2.3")),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"name, value, prop, expected",
|
||||
(
|
||||
("mylib", None, "as_lib_dep", "mylib"),
|
||||
("mylib", None, "as_tuple", ("mylib", None)),
|
||||
("mylib", "1.2.3", "as_lib_dep", "mylib@1.2.3"),
|
||||
("mylib", "1.2.3", "as_tuple", ("mylib", "1.2.3")),
|
||||
),
|
||||
)
|
||||
def test_properties(self, name, value, prop, expected):
|
||||
target = core.Library(name, value)
|
||||
|
||||
@@ -433,16 +459,19 @@ class TestLibrary:
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.3"), True),
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.4"), False),
|
||||
("__eq__", core.Library(name="libbar", version="1.2.3"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.3"), True),
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.4"), False),
|
||||
("__eq__", core.Library(name="libbar", version="1.2.3"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.Library(name="libfoo", version="1.2.3")
|
||||
|
||||
|
@@ -9,18 +9,18 @@ from esphome import cpp_types as ct
|
||||
|
||||
|
||||
class TestExpressions:
|
||||
@pytest.mark.parametrize("target, expected", (
|
||||
(cg.RawExpression("foo && bar"), "foo && bar"),
|
||||
|
||||
(cg.AssignmentExpression(None, None, "foo", "bar", None), 'foo = "bar"'),
|
||||
(cg.AssignmentExpression(ct.float_, "*", "foo", 1, None), 'float *foo = 1'),
|
||||
(cg.AssignmentExpression(ct.float_, "", "foo", 1, None), 'float foo = 1'),
|
||||
|
||||
(cg.VariableDeclarationExpression(ct.int32, "*", "foo"), "int32_t *foo"),
|
||||
(cg.VariableDeclarationExpression(ct.int32, "", "foo"), "int32_t foo"),
|
||||
|
||||
(cg.ParameterExpression(ct.std_string, "foo"), "std::string foo"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"target, expected",
|
||||
(
|
||||
(cg.RawExpression("foo && bar"), "foo && bar"),
|
||||
(cg.AssignmentExpression(None, None, "foo", "bar", None), 'foo = "bar"'),
|
||||
(cg.AssignmentExpression(ct.float_, "*", "foo", 1, None), "float *foo = 1"),
|
||||
(cg.AssignmentExpression(ct.float_, "", "foo", 1, None), "float foo = 1"),
|
||||
(cg.VariableDeclarationExpression(ct.int32, "*", "foo"), "int32_t *foo"),
|
||||
(cg.VariableDeclarationExpression(ct.int32, "", "foo"), "int32_t foo"),
|
||||
(cg.ParameterExpression(ct.std_string, "foo"), "std::string foo"),
|
||||
),
|
||||
)
|
||||
def test_str__simple(self, target: cg.Expression, expected: str):
|
||||
actual = str(target)
|
||||
|
||||
@@ -67,10 +67,7 @@ class TestTemplateArguments:
|
||||
|
||||
class TestCallExpression:
|
||||
def test_str__no_template_args(self):
|
||||
target = cg.CallExpression(
|
||||
cg.RawExpression("my_function"),
|
||||
1, "2", False
|
||||
)
|
||||
target = cg.CallExpression(cg.RawExpression("my_function"), 1, "2", False)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
@@ -80,7 +77,9 @@ class TestCallExpression:
|
||||
target = cg.CallExpression(
|
||||
cg.RawExpression("my_function"),
|
||||
cg.TemplateArguments(int, float),
|
||||
1, "2", False
|
||||
1,
|
||||
"2",
|
||||
False,
|
||||
)
|
||||
|
||||
actual = str(target)
|
||||
@@ -100,36 +99,32 @@ class TestStructInitializer:
|
||||
|
||||
actual = str(target)
|
||||
|
||||
assert actual == 'foo::MyStruct{\n' \
|
||||
' .state = "on",\n' \
|
||||
' .min_length = 1,\n' \
|
||||
' .max_length = 5,\n' \
|
||||
'}'
|
||||
assert (
|
||||
actual == "foo::MyStruct{\n"
|
||||
' .state = "on",\n'
|
||||
" .min_length = 1,\n"
|
||||
" .max_length = 5,\n"
|
||||
"}"
|
||||
)
|
||||
|
||||
|
||||
class TestArrayInitializer:
|
||||
def test_str__empty(self):
|
||||
target = cg.ArrayInitializer(
|
||||
None, None
|
||||
)
|
||||
target = cg.ArrayInitializer(None, None)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
assert actual == "{}"
|
||||
|
||||
def test_str__not_multiline(self):
|
||||
target = cg.ArrayInitializer(
|
||||
1, 2, 3, 4
|
||||
)
|
||||
target = cg.ArrayInitializer(1, 2, 3, 4)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
assert actual == "{1, 2, 3, 4}"
|
||||
|
||||
def test_str__multiline(self):
|
||||
target = cg.ArrayInitializer(
|
||||
1, 2, 3, 4, multiline=True
|
||||
)
|
||||
target = cg.ArrayInitializer(1, 2, 3, 4, multiline=True)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
@@ -169,7 +164,7 @@ class TestLambdaExpression:
|
||||
|
||||
def test_str__with_return(self):
|
||||
target = cg.LambdaExpression(
|
||||
("return (foo == 5) && (bar < 10));", ),
|
||||
("return (foo == 5) && (bar < 10));",),
|
||||
cg.ParameterListExpression((int, "foo"), (float, "bar")),
|
||||
"=",
|
||||
bool,
|
||||
@@ -185,27 +180,26 @@ class TestLambdaExpression:
|
||||
|
||||
|
||||
class TestLiterals:
|
||||
@pytest.mark.parametrize("target, expected", (
|
||||
(cg.StringLiteral("foo"), '"foo"'),
|
||||
|
||||
(cg.IntLiteral(0), "0"),
|
||||
(cg.IntLiteral(42), "42"),
|
||||
(cg.IntLiteral(4304967295), "4304967295ULL"),
|
||||
(cg.IntLiteral(2150483647), "2150483647UL"),
|
||||
(cg.IntLiteral(-2150083647), "-2150083647LL"),
|
||||
|
||||
(cg.BoolLiteral(True), "true"),
|
||||
(cg.BoolLiteral(False), "false"),
|
||||
|
||||
(cg.HexIntLiteral(0), "0x00"),
|
||||
(cg.HexIntLiteral(42), "0x2A"),
|
||||
(cg.HexIntLiteral(682), "0x2AA"),
|
||||
|
||||
(cg.FloatLiteral(0.0), "0.0f"),
|
||||
(cg.FloatLiteral(4.2), "4.2f"),
|
||||
(cg.FloatLiteral(1.23456789), "1.23456789f"),
|
||||
(cg.FloatLiteral(math.nan), "NAN"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"target, expected",
|
||||
(
|
||||
(cg.StringLiteral("foo"), '"foo"'),
|
||||
(cg.IntLiteral(0), "0"),
|
||||
(cg.IntLiteral(42), "42"),
|
||||
(cg.IntLiteral(4304967295), "4304967295ULL"),
|
||||
(cg.IntLiteral(2150483647), "2150483647UL"),
|
||||
(cg.IntLiteral(-2150083647), "-2150083647LL"),
|
||||
(cg.BoolLiteral(True), "true"),
|
||||
(cg.BoolLiteral(False), "false"),
|
||||
(cg.HexIntLiteral(0), "0x00"),
|
||||
(cg.HexIntLiteral(42), "0x2A"),
|
||||
(cg.HexIntLiteral(682), "0x2AA"),
|
||||
(cg.FloatLiteral(0.0), "0.0f"),
|
||||
(cg.FloatLiteral(4.2), "4.2f"),
|
||||
(cg.FloatLiteral(1.23456789), "1.23456789f"),
|
||||
(cg.FloatLiteral(math.nan), "NAN"),
|
||||
),
|
||||
)
|
||||
def test_str__simple(self, target: cg.Literal, expected: str):
|
||||
actual = str(target)
|
||||
|
||||
@@ -216,7 +210,9 @@ FAKE_ENUM_VALUE = cg.EnumValue()
|
||||
FAKE_ENUM_VALUE.enum_value = "foo"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj, expected_type", (
|
||||
@pytest.mark.parametrize(
|
||||
"obj, expected_type",
|
||||
(
|
||||
(cg.RawExpression("foo"), cg.RawExpression),
|
||||
(FAKE_ENUM_VALUE, cg.StringLiteral),
|
||||
(True, cg.BoolLiteral),
|
||||
@@ -230,49 +226,59 @@ FAKE_ENUM_VALUE.enum_value = "foo"
|
||||
(cg.TimePeriodMinutes(minutes=42), cg.IntLiteral),
|
||||
((1, 2, 3), cg.ArrayInitializer),
|
||||
([1, 2, 3], cg.ArrayInitializer),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_safe_exp__allowed_values(obj, expected_type):
|
||||
actual = cg.safe_exp(obj)
|
||||
|
||||
assert isinstance(actual, expected_type)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj, expected_type", (
|
||||
@pytest.mark.parametrize(
|
||||
"obj, expected_type",
|
||||
(
|
||||
(bool, ct.bool_),
|
||||
(int, ct.int32),
|
||||
(float, ct.float_),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_safe_exp__allowed_types(obj, expected_type):
|
||||
actual = cg.safe_exp(obj)
|
||||
|
||||
assert actual is expected_type
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj, expected_error", (
|
||||
@pytest.mark.parametrize(
|
||||
"obj, expected_error",
|
||||
(
|
||||
(cg.ID("foo"), "Object foo is an ID."),
|
||||
((x for x in "foo"), r"Object <.*> is a coroutine."),
|
||||
(None, "Object is not an expression"),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_safe_exp__invalid_values(obj, expected_error):
|
||||
with pytest.raises(ValueError, match=expected_error):
|
||||
cg.safe_exp(obj)
|
||||
|
||||
|
||||
class TestStatements:
|
||||
@pytest.mark.parametrize("target, expected", (
|
||||
(cg.RawStatement("foo && bar"), "foo && bar"),
|
||||
|
||||
(cg.ExpressionStatement("foo"), '"foo";'),
|
||||
(cg.ExpressionStatement(42), '42;'),
|
||||
|
||||
(cg.LineComment("The point of foo is..."), "// The point of foo is..."),
|
||||
(cg.LineComment("Help help\nI'm being repressed"), "// Help help\n// I'm being repressed"),
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"target, expected",
|
||||
(
|
||||
cg.ProgmemAssignmentExpression(ct.uint16, "foo", "bar", None),
|
||||
'static const uint16_t foo[] PROGMEM = "bar"'
|
||||
)
|
||||
))
|
||||
(cg.RawStatement("foo && bar"), "foo && bar"),
|
||||
(cg.ExpressionStatement("foo"), '"foo";'),
|
||||
(cg.ExpressionStatement(42), "42;"),
|
||||
(cg.LineComment("The point of foo is..."), "// The point of foo is..."),
|
||||
(
|
||||
cg.LineComment("Help help\nI'm being repressed"),
|
||||
"// Help help\n// I'm being repressed",
|
||||
),
|
||||
(
|
||||
cg.ProgmemAssignmentExpression(ct.uint16, "foo", "bar", None),
|
||||
'static const uint16_t foo[] PROGMEM = "bar"',
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_str__simple(self, target: cg.Statement, expected: str):
|
||||
actual = str(target)
|
||||
|
||||
|
@@ -15,11 +15,9 @@ def test_gpio_pin_expression__conf_is_none(monkeypatch):
|
||||
|
||||
|
||||
def test_gpio_pin_expression__new_pin(monkeypatch):
|
||||
target = ch.gpio_pin_expression({
|
||||
const.CONF_NUMBER: 42,
|
||||
const.CONF_MODE: "input",
|
||||
const.CONF_INVERTED: False
|
||||
})
|
||||
target = ch.gpio_pin_expression(
|
||||
{const.CONF_NUMBER: 42, const.CONF_MODE: "input", const.CONF_INVERTED: False}
|
||||
)
|
||||
|
||||
actual = next(target)
|
||||
|
||||
@@ -71,10 +69,13 @@ def test_register_component__with_setup_priority(monkeypatch):
|
||||
add_mock = Mock()
|
||||
monkeypatch.setattr(ch, "add", add_mock)
|
||||
|
||||
target = ch.register_component(var, {
|
||||
const.CONF_SETUP_PRIORITY: "123",
|
||||
const.CONF_UPDATE_INTERVAL: "456",
|
||||
})
|
||||
target = ch.register_component(
|
||||
var,
|
||||
{
|
||||
const.CONF_SETUP_PRIORITY: "123",
|
||||
const.CONF_UPDATE_INTERVAL: "456",
|
||||
},
|
||||
)
|
||||
|
||||
actual = next(target)
|
||||
|
||||
|
@@ -6,69 +6,89 @@ from hypothesis.provisional import ip_addresses
|
||||
from esphome import helpers
|
||||
|
||||
|
||||
@pytest.mark.parametrize("preferred_string, current_strings, expected", (
|
||||
("foo", [], "foo"),
|
||||
# TODO: Should this actually start at 1?
|
||||
("foo", ["foo"], "foo_2"),
|
||||
("foo", ("foo",), "foo_2"),
|
||||
("foo", ("foo", "foo_2"), "foo_3"),
|
||||
("foo", ("foo", "foo_2", "foo_2"), "foo_3"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"preferred_string, current_strings, expected",
|
||||
(
|
||||
("foo", [], "foo"),
|
||||
# TODO: Should this actually start at 1?
|
||||
("foo", ["foo"], "foo_2"),
|
||||
("foo", ("foo",), "foo_2"),
|
||||
("foo", ("foo", "foo_2"), "foo_3"),
|
||||
("foo", ("foo", "foo_2", "foo_2"), "foo_3"),
|
||||
),
|
||||
)
|
||||
def test_ensure_unique_string(preferred_string, current_strings, expected):
|
||||
actual = helpers.ensure_unique_string(preferred_string, current_strings)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", (
|
||||
("foo", "foo"),
|
||||
("foo\nbar", "foo\nbar"),
|
||||
("foo\nbar\neek", "foo\n bar\neek"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", "foo"),
|
||||
("foo\nbar", "foo\nbar"),
|
||||
("foo\nbar\neek", "foo\n bar\neek"),
|
||||
),
|
||||
)
|
||||
def test_indent_all_but_first_and_last(text, expected):
|
||||
actual = helpers.indent_all_but_first_and_last(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", (
|
||||
("foo", [" foo"]),
|
||||
("foo\nbar", [" foo", " bar"]),
|
||||
("foo\nbar\neek", [" foo", " bar", " eek"]),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", [" foo"]),
|
||||
("foo\nbar", [" foo", " bar"]),
|
||||
("foo\nbar\neek", [" foo", " bar", " eek"]),
|
||||
),
|
||||
)
|
||||
def test_indent_list(text, expected):
|
||||
actual = helpers.indent_list(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", (
|
||||
("foo", " foo"),
|
||||
("foo\nbar", " foo\n bar"),
|
||||
("foo\nbar\neek", " foo\n bar\n eek"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", " foo"),
|
||||
("foo\nbar", " foo\n bar"),
|
||||
("foo\nbar\neek", " foo\n bar\n eek"),
|
||||
),
|
||||
)
|
||||
def test_indent(text, expected):
|
||||
actual = helpers.indent(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("string, expected", (
|
||||
("foo", '"foo"'),
|
||||
("foo\nbar", '"foo\\012bar"'),
|
||||
("foo\\bar", '"foo\\134bar"'),
|
||||
('foo "bar"', '"foo \\042bar\\042"'),
|
||||
('foo 🐍', '"foo \\360\\237\\220\\215"'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"string, expected",
|
||||
(
|
||||
("foo", '"foo"'),
|
||||
("foo\nbar", '"foo\\012bar"'),
|
||||
("foo\\bar", '"foo\\134bar"'),
|
||||
('foo "bar"', '"foo \\042bar\\042"'),
|
||||
("foo 🐍", '"foo \\360\\237\\220\\215"'),
|
||||
),
|
||||
)
|
||||
def test_cpp_string_escape(string, expected):
|
||||
actual = helpers.cpp_string_escape(string)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("host", (
|
||||
"127.0.0", "localhost", "127.0.0.b",
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"host",
|
||||
(
|
||||
"127.0.0",
|
||||
"localhost",
|
||||
"127.0.0.b",
|
||||
),
|
||||
)
|
||||
def test_is_ip_address__invalid(host):
|
||||
actual = helpers.is_ip_address(host)
|
||||
|
||||
@@ -82,13 +102,16 @@ def test_is_ip_address__valid(value):
|
||||
assert actual is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("var, value, default, expected", (
|
||||
("FOO", None, False, False),
|
||||
("FOO", None, True, True),
|
||||
("FOO", "", False, False),
|
||||
("FOO", "Yes", False, True),
|
||||
("FOO", "123", False, True),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"var, value, default, expected",
|
||||
(
|
||||
("FOO", None, False, False),
|
||||
("FOO", None, True, True),
|
||||
("FOO", "", False, False),
|
||||
("FOO", "Yes", False, True),
|
||||
("FOO", "123", False, True),
|
||||
),
|
||||
)
|
||||
def test_get_bool_env(monkeypatch, var, value, default, expected):
|
||||
if value is None:
|
||||
monkeypatch.delenv(var, raising=False)
|
||||
@@ -100,10 +123,7 @@ def test_get_bool_env(monkeypatch, var, value, default, expected):
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
(None, False),
|
||||
("Yes", True)
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", ((None, False), ("Yes", True)))
|
||||
def test_is_hassio(monkeypatch, value, expected):
|
||||
if value is None:
|
||||
monkeypatch.delenv("ESPHOME_IS_HASSIO", raising=False)
|
||||
@@ -185,20 +205,23 @@ class Test_copy_file_if_changed:
|
||||
assert src.read_text() == dst.read_text()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("file1, file2, expected", (
|
||||
# Same file
|
||||
("file-a.txt", "file-a.txt", True),
|
||||
# Different files, different size
|
||||
("file-a.txt", "file-b_1.txt", False),
|
||||
# Different files, same size
|
||||
("file-a.txt", "file-c.txt", False),
|
||||
# Same files
|
||||
("file-b_1.txt", "file-b_2.txt", True),
|
||||
# Not a file
|
||||
("file-a.txt", "", False),
|
||||
# File doesn't exist
|
||||
("file-a.txt", "file-d.txt", False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"file1, file2, expected",
|
||||
(
|
||||
# Same file
|
||||
("file-a.txt", "file-a.txt", True),
|
||||
# Different files, different size
|
||||
("file-a.txt", "file-b_1.txt", False),
|
||||
# Different files, same size
|
||||
("file-a.txt", "file-c.txt", False),
|
||||
# Same files
|
||||
("file-b_1.txt", "file-b_2.txt", True),
|
||||
# Not a file
|
||||
("file-a.txt", "", False),
|
||||
# File doesn't exist
|
||||
("file-a.txt", "file-d.txt", False),
|
||||
),
|
||||
)
|
||||
def test_file_compare(fixture_path, file1, file2, expected):
|
||||
path1 = fixture_path / "helpers" / file1
|
||||
path2 = fixture_path / "helpers" / file2
|
||||
|
@@ -15,12 +15,12 @@ from esphome import pins
|
||||
|
||||
|
||||
MOCK_ESP8266_BOARD_ID = "_mock_esp8266"
|
||||
MOCK_ESP8266_PINS = {'X0': 16, 'X1': 5, 'X2': 4, 'LED': 2}
|
||||
MOCK_ESP8266_PINS = {"X0": 16, "X1": 5, "X2": 4, "LED": 2}
|
||||
MOCK_ESP8266_BOARD_ALIAS_ID = "_mock_esp8266_alias"
|
||||
MOCK_ESP8266_FLASH_SIZE = pins.FLASH_SIZE_2_MB
|
||||
|
||||
MOCK_ESP32_BOARD_ID = "_mock_esp32"
|
||||
MOCK_ESP32_PINS = {'Y0': 12, 'Y1': 8, 'Y2': 3, 'LED': 9, "A0": 8}
|
||||
MOCK_ESP32_PINS = {"Y0": 12, "Y1": 8, "Y2": 3, "LED": 9, "A0": 8}
|
||||
MOCK_ESP32_BOARD_ALIAS_ID = "_mock_esp32_alias"
|
||||
|
||||
UNKNOWN_PLATFORM = "STM32"
|
||||
@@ -68,10 +68,13 @@ def core_esp32(core):
|
||||
|
||||
|
||||
class Test_lookup_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("X1", 5),
|
||||
("MOSI", 13),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp8266_pin(self, core_esp8266, value, expected):
|
||||
actual = pins._lookup_pin(value)
|
||||
|
||||
@@ -84,11 +87,14 @@ class Test_lookup_pin:
|
||||
|
||||
assert actual == 4
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y1", 8),
|
||||
("A0", 8),
|
||||
("MOSI", 23),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_pin(self, core_esp32, value, expected):
|
||||
actual = pins._lookup_pin(value)
|
||||
|
||||
@@ -102,7 +108,9 @@ class Test_lookup_pin:
|
||||
assert actual == 3
|
||||
|
||||
def test_invalid_pin(self, core_esp8266):
|
||||
with pytest.raises(Invalid, match="Cannot resolve pin name 'X42' for board _mock_esp8266."):
|
||||
with pytest.raises(
|
||||
Invalid, match="Cannot resolve pin name 'X42' for board _mock_esp8266."
|
||||
):
|
||||
pins._lookup_pin("X42")
|
||||
|
||||
def test_unsupported_platform(self, core):
|
||||
@@ -113,13 +121,16 @@ class Test_lookup_pin:
|
||||
|
||||
|
||||
class Test_translate_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
(2, 2),
|
||||
("3", 3),
|
||||
("GPIO4", 4),
|
||||
("TX", 1),
|
||||
("Y0", 12),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_values(self, core_esp32, value, expected):
|
||||
actual = pins._translate_pin(value)
|
||||
|
||||
@@ -137,7 +148,9 @@ class Test_validate_gpio_pin:
|
||||
|
||||
assert actual == 22
|
||||
|
||||
@pytest.mark.parametrize("value, match", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, match",
|
||||
(
|
||||
(-1, "ESP32: Invalid pin number: -1"),
|
||||
(40, "ESP32: Invalid pin number: 40"),
|
||||
(6, "This pin cannot be used on ESP32s and"),
|
||||
@@ -150,7 +163,8 @@ class Test_validate_gpio_pin:
|
||||
(29, "The pin GPIO29 is not usable on ESP32s"),
|
||||
(30, "The pin GPIO30 is not usable on ESP32s"),
|
||||
(31, "The pin GPIO31 is not usable on ESP32s"),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_esp32_invalid_pin(self, core_esp32, value, match):
|
||||
with pytest.raises(Invalid, match=match):
|
||||
pins.validate_gpio_pin(value)
|
||||
@@ -168,14 +182,17 @@ class Test_validate_gpio_pin:
|
||||
|
||||
assert actual == 12
|
||||
|
||||
@pytest.mark.parametrize("value, match", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, match",
|
||||
(
|
||||
(-1, "ESP8266: Invalid pin number: -1"),
|
||||
(18, "ESP8266: Invalid pin number: 18"),
|
||||
(6, "This pin cannot be used on ESP8266s and"),
|
||||
(7, "This pin cannot be used on ESP8266s and"),
|
||||
(8, "This pin cannot be used on ESP8266s and"),
|
||||
(11, "This pin cannot be used on ESP8266s and"),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_esp8266_invalid_pin(self, core_esp8266, value, match):
|
||||
with pytest.raises(Invalid, match=match):
|
||||
pins.validate_gpio_pin(value)
|
||||
@@ -196,18 +213,19 @@ class Test_validate_gpio_pin:
|
||||
|
||||
|
||||
class Test_input_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
("X0", 16),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", (("X0", 16),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.input_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y0", 12),
|
||||
(17, 17),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.input_pin(value)
|
||||
|
||||
@@ -226,18 +244,19 @@ class Test_input_pin:
|
||||
|
||||
|
||||
class Test_input_pullup_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
("X0", 16),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", (("X0", 16),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.input_pullup_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y0", 12),
|
||||
(17, 17),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.input_pullup_pin(value)
|
||||
|
||||
@@ -256,18 +275,19 @@ class Test_input_pullup_pin:
|
||||
|
||||
|
||||
class Test_output_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
("X0", 16),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", (("X0", 16),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.output_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y0", 12),
|
||||
(17, 17),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.output_pin(value)
|
||||
|
||||
@@ -291,18 +311,19 @@ class Test_output_pin:
|
||||
|
||||
|
||||
class Test_analog_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
(17, 17),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", ((17, 17),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.analog_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
(32, 32),
|
||||
(39, 39),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.analog_pin(value)
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
""" Tests for the wizard.py file """
|
||||
"""Tests for the wizard.py file."""
|
||||
|
||||
import esphome.wizard as wz
|
||||
import pytest
|
||||
@@ -14,7 +14,7 @@ def default_config():
|
||||
"board": "test_board",
|
||||
"ssid": "test_ssid",
|
||||
"psk": "test_psk",
|
||||
"password": ""
|
||||
"password": "",
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ def test_sanitize_quotes_replaces_with_escaped_char():
|
||||
The sanitize_quotes function should replace double quotes with their escaped equivalents
|
||||
"""
|
||||
# Given
|
||||
input_str = "\"key\": \"value\""
|
||||
input_str = '"key": "value"'
|
||||
|
||||
# When
|
||||
output_str = wz.sanitize_double_quotes(input_str)
|
||||
|
||||
# Then
|
||||
assert output_str == "\\\"key\\\": \\\"value\\\""
|
||||
assert output_str == '\\"key\\": \\"value\\"'
|
||||
|
||||
|
||||
def test_config_file_fallback_ap_includes_descriptive_name(default_config):
|
||||
@@ -55,7 +55,7 @@ def test_config_file_fallback_ap_includes_descriptive_name(default_config):
|
||||
config = wz.wizard_file(**default_config)
|
||||
|
||||
# Then
|
||||
assert f"ssid: \"Test Node Fallback Hotspot\"" in config
|
||||
assert 'ssid: "Test Node Fallback Hotspot"' in config
|
||||
|
||||
|
||||
def test_config_file_fallback_ap_name_less_than_32_chars(default_config):
|
||||
@@ -70,7 +70,7 @@ def test_config_file_fallback_ap_name_less_than_32_chars(default_config):
|
||||
config = wz.wizard_file(**default_config)
|
||||
|
||||
# Then
|
||||
assert f"ssid: \"A Very Long Name For This Node\"" in config
|
||||
assert 'ssid: "A Very Long Name For This Node"' in config
|
||||
|
||||
|
||||
def test_config_file_should_include_ota(default_config):
|
||||
@@ -115,7 +115,9 @@ def test_wizard_write_sets_platform(default_config, tmp_path, monkeypatch):
|
||||
assert f"platform: {default_config['platform']}" in generated_config
|
||||
|
||||
|
||||
def test_wizard_write_defaults_platform_from_board_esp8266(default_config, tmp_path, monkeypatch):
|
||||
def test_wizard_write_defaults_platform_from_board_esp8266(
|
||||
default_config, tmp_path, monkeypatch
|
||||
):
|
||||
"""
|
||||
If the platform is not explicitly set, use "ESP8266" if the board is one of the ESP8266 boards
|
||||
"""
|
||||
@@ -133,7 +135,9 @@ def test_wizard_write_defaults_platform_from_board_esp8266(default_config, tmp_p
|
||||
assert "platform: ESP8266" in generated_config
|
||||
|
||||
|
||||
def test_wizard_write_defaults_platform_from_board_esp32(default_config, tmp_path, monkeypatch):
|
||||
def test_wizard_write_defaults_platform_from_board_esp32(
|
||||
default_config, tmp_path, monkeypatch
|
||||
):
|
||||
"""
|
||||
If the platform is not explicitly set, use "ESP32" if the board is not one of the ESP8266 boards
|
||||
"""
|
||||
@@ -167,7 +171,9 @@ def test_safe_print_step_prints_step_number_and_description(monkeypatch):
|
||||
|
||||
# Then
|
||||
# Collect arguments to all safe_print() calls (substituting "" for any empty ones)
|
||||
all_args = [call.args[0] if len(call.args) else "" for call in wz.safe_print.call_args_list]
|
||||
all_args = [
|
||||
call.args[0] if len(call.args) else "" for call in wz.safe_print.call_args_list
|
||||
]
|
||||
|
||||
assert any(step_desc == arg for arg in all_args)
|
||||
assert any(f"STEP {step_num}" in arg for arg in all_args)
|
||||
@@ -212,7 +218,7 @@ def test_strip_accents_removes_diacritics():
|
||||
"""
|
||||
|
||||
# Given
|
||||
input_str = u"Kühne"
|
||||
input_str = "Kühne"
|
||||
expected_str = "Kuhne"
|
||||
|
||||
# When
|
||||
@@ -264,7 +270,7 @@ def test_wizard_accepts_default_answers_esp8266(tmpdir, monkeypatch, wizard_answ
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -286,7 +292,7 @@ def test_wizard_accepts_default_answers_esp32(tmpdir, monkeypatch, wizard_answer
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -306,14 +312,16 @@ def test_wizard_offers_better_node_name(tmpdir, monkeypatch, wizard_answers):
|
||||
# Given
|
||||
wizard_answers[0] = "Küche #2"
|
||||
expected_name = "kuche_2"
|
||||
monkeypatch.setattr(wz, "default_input", MagicMock(side_effect=lambda _, default: default))
|
||||
monkeypatch.setattr(
|
||||
wz, "default_input", MagicMock(side_effect=lambda _, default: default)
|
||||
)
|
||||
|
||||
config_file = tmpdir.join("test.yaml")
|
||||
input_mock = MagicMock(side_effect=wizard_answers)
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -336,7 +344,7 @@ def test_wizard_requires_correct_platform(tmpdir, monkeypatch, wizard_answers):
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -358,7 +366,7 @@ def test_wizard_requires_correct_board(tmpdir, monkeypatch, wizard_answers):
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -380,7 +388,7 @@ def test_wizard_requires_valid_ssid(tmpdir, monkeypatch, wizard_answers):
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
|
Reference in New Issue
Block a user