1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-25 21:23:53 +01:00

[substitutions] !extend and !remove now support substitutions and jinja (#11203)

This commit is contained in:
Javier Peletier
2025-10-19 23:31:25 +02:00
committed by GitHub
parent 1a2057df30
commit 1e1fefbd0a
7 changed files with 171 additions and 136 deletions

View File

@@ -6,6 +6,7 @@ from unittest.mock import MagicMock, patch
import pytest
from esphome.components.packages import do_packages_pass
from esphome.config import resolve_extend_remove
from esphome.config_helpers import Extend, Remove
import esphome.config_validation as cv
from esphome.const import (
@@ -64,13 +65,20 @@ def fixture_basic_esphome():
return {CONF_NAME: TEST_DEVICE_NAME, CONF_PLATFORM: TEST_PLATFORM}
def packages_pass(config):
"""Wrapper around packages_pass that also resolves Extend and Remove."""
config = do_packages_pass(config)
resolve_extend_remove(config)
return config
def test_package_unused(basic_esphome, basic_wifi):
"""
Ensures do_package_pass does not change a config if packages aren't used.
"""
config = {CONF_ESPHOME: basic_esphome, CONF_WIFI: basic_wifi}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == config
@@ -83,7 +91,7 @@ def test_package_invalid_dict(basic_esphome, basic_wifi):
config = {CONF_ESPHOME: basic_esphome, CONF_PACKAGES: basic_wifi | {CONF_URL: ""}}
with pytest.raises(cv.Invalid):
do_packages_pass(config)
packages_pass(config)
def test_package_include(basic_wifi, basic_esphome):
@@ -99,7 +107,7 @@ def test_package_include(basic_wifi, basic_esphome):
expected = {CONF_ESPHOME: basic_esphome, CONF_WIFI: basic_wifi}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -124,7 +132,7 @@ def test_package_append(basic_wifi, basic_esphome):
},
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -148,7 +156,7 @@ def test_package_override(basic_wifi, basic_esphome):
},
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -177,7 +185,7 @@ def test_multiple_package_order():
},
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -233,7 +241,7 @@ def test_package_list_merge():
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -311,7 +319,7 @@ def test_package_list_merge_by_id():
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -350,13 +358,13 @@ def test_package_merge_by_id_with_list():
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
def test_package_merge_by_missing_id():
"""
Ensures that components with missing IDs are not merged.
Ensures that a validation error is thrown when trying to extend a missing ID.
"""
config = {
@@ -379,25 +387,15 @@ def test_package_merge_by_missing_id():
],
}
expected = {
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_1,
CONF_FILTERS: [{CONF_MULTIPLY: 42.0}],
},
{
CONF_ID: TEST_SENSOR_ID_1,
CONF_FILTERS: [{CONF_MULTIPLY: 10.0}],
},
{
CONF_ID: Extend(TEST_SENSOR_ID_2),
CONF_FILTERS: [{CONF_OFFSET: 146.0}],
},
]
}
error_raised = False
try:
packages_pass(config)
assert False, "Expected validation error for missing ID"
except cv.Invalid as err:
error_raised = True
assert err.path == [CONF_SENSOR, 2]
actual = do_packages_pass(config)
assert actual == expected
assert error_raised
def test_package_list_remove_by_id():
@@ -447,7 +445,7 @@ def test_package_list_remove_by_id():
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -493,7 +491,7 @@ def test_multiple_package_list_remove_by_id():
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -514,7 +512,7 @@ def test_package_dict_remove_by_id(basic_wifi, basic_esphome):
CONF_ESPHOME: basic_esphome,
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -545,7 +543,6 @@ def test_package_remove_by_missing_id():
}
expected = {
"missing_key": Remove(),
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_1,
@@ -555,14 +552,10 @@ def test_package_remove_by_missing_id():
CONF_ID: TEST_SENSOR_ID_1,
CONF_FILTERS: [{CONF_MULTIPLY: 10.0}],
},
{
CONF_ID: Remove(TEST_SENSOR_ID_2),
CONF_FILTERS: [{CONF_OFFSET: 146.0}],
},
],
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -634,7 +627,7 @@ def test_remote_packages_with_files_list(
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected
@@ -730,5 +723,5 @@ def test_remote_packages_with_files_and_vars(
]
}
actual = do_packages_pass(config)
actual = packages_pass(config)
assert actual == expected