diff --git a/esphome/core.py b/esphome/core.py index 7734636a76..4b1d3b2115 100644 --- a/esphome/core.py +++ b/esphome/core.py @@ -230,10 +230,23 @@ class Lambda: self._parts = None self._requires_ids = None + # https://stackoverflow.com/a/241506/229052 + def comment_remover(self, text): + def replacer(match): + s = match.group(0) + if s.startswith('/'): + return " " # note: a space and not an empty string + return s + pattern = re.compile( + r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', + re.DOTALL | re.MULTILINE + ) + return re.sub(pattern, replacer, text) + @property def parts(self): if self._parts is None: - self._parts = re.split(LAMBDA_PROG, self._value) + self._parts = re.split(LAMBDA_PROG, self.comment_remover(self._value)) return self._parts @property diff --git a/tests/unit_tests/test_core.py b/tests/unit_tests/test_core.py index c02aed6447..14f6990bd9 100644 --- a/tests/unit_tests/test_core.py +++ b/tests/unit_tests/test_core.py @@ -9,11 +9,11 @@ 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 + (1, "0x01"), + (255, "0xFF"), + (128, "0x80"), + (256, "0x100"), + (-1, "-0x01"), # TODO: this currently fails )) def test_str(self, value, expected): target = core.HexInt(value) @@ -88,24 +88,24 @@ 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}), + ({}, {}), + ({"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) @@ -119,24 +119,24 @@ class TestTimePeriod: 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"), + ({}, "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) @@ -146,59 +146,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), + ("__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), + ("__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), + ("__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), + ("__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), + ("__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), + ("__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) @@ -211,6 +211,10 @@ class TestTimePeriod: SAMPLE_LAMBDA = """ it.strftime(64, 0, id(my_font), TextAlign::TOP_CENTER, "%H:%M:%S", id(esptime).now()); it.printf(64, 16, id(my_font2), TextAlign::TOP_CENTER, "%.1f°C (%.1f%%)", id( office_tmp ).state, id(office_hmd).state); +//id(my_commented_id) +int x = 4;/* id(my_commented_id2) +id(my_commented_id3) +*/ """ @@ -246,7 +250,7 @@ class TestLambda: "state, ", "office_hmd", ".", - "state);" + "state);\n \nint x = 4; " ] def test_requires_ids(self): @@ -293,11 +297,11 @@ class TestID: 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), + ("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) @@ -305,10 +309,10 @@ class TestID: 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"), + ([], "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,13 +330,13 @@ class TestID: 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), + ("__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") @@ -381,12 +385,12 @@ 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)), + ("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) @@ -396,16 +400,16 @@ 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), + ("__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) @@ -417,10 +421,10 @@ 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")), + ("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) @@ -430,14 +434,14 @@ 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), + ("__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")