|
1 | 1 | import copy |
2 | 2 |
|
| 3 | +import pytest |
| 4 | + |
3 | 5 | from flow360.component.simulation.framework.base_model import Flow360BaseModel |
4 | 6 | from flow360.component.simulation.framework.entity_selector import ( |
5 | 7 | EntityDictDatabase, |
| 8 | + EntitySelector, |
6 | 9 | collect_and_tokenize_selectors_in_place, |
7 | 10 | expand_entity_selectors_in_place, |
8 | 11 | ) |
@@ -83,6 +86,22 @@ def test_entity_selector_token_flow(): |
83 | 86 | assert len(s2) == 2 |
84 | 87 | assert {e["name"] for e in s2} == {"wing_left", "wing_right"} |
85 | 88 |
|
| 89 | + # 6. Verify selectors are expanded from tokens to full dicts (not strings) |
| 90 | + sel1 = expanded_params["models"][0]["selectors"] |
| 91 | + sel2 = expanded_params["models"][1]["selectors"] |
| 92 | + |
| 93 | + assert len(sel1) == 1 |
| 94 | + assert isinstance(sel1[0], dict), "Selector token should be expanded to dict" |
| 95 | + assert sel1[0]["selector_id"] == "sel1-token" |
| 96 | + assert sel1[0]["name"] == "sel1" |
| 97 | + |
| 98 | + assert len(sel2) == 1 |
| 99 | + assert isinstance(sel2[0], dict), "Selector token should be expanded to dict" |
| 100 | + |
| 101 | + # 7. Verify expanded selectors can be validated as EntitySelector |
| 102 | + EntitySelector.model_validate(sel1[0]) |
| 103 | + EntitySelector.model_validate(sel2[0]) |
| 104 | + |
86 | 105 |
|
87 | 106 | def test_entity_selector_token_round_trip_validation(): |
88 | 107 | params = { |
@@ -176,3 +195,44 @@ def test_entity_selector_mixed_token_and_dict(): |
176 | 195 | assert "wing_left" in names |
177 | 196 | assert "fuselage" in names |
178 | 197 | assert len(names) == 2 |
| 198 | + |
| 199 | + # Verify selectors are all dicts after expansion (token resolved, inline kept) |
| 200 | + selectors = expanded["model"]["selectors"] |
| 201 | + assert len(selectors) == 2 |
| 202 | + assert all(isinstance(s, dict) for s in selectors), "All selectors should be dicts" |
| 203 | + assert selectors[0]["selector_id"] == "sel-cache-id" # Token was expanded |
| 204 | + assert selectors[1]["selector_id"] == "sel-inline-id" # Inline kept as-is |
| 205 | + |
| 206 | + # Verify both can be validated as EntitySelector |
| 207 | + for sel in selectors: |
| 208 | + EntitySelector.model_validate(sel) |
| 209 | + |
| 210 | + |
| 211 | +def test_entity_selector_unknown_token_raises_error(): |
| 212 | + """Test that referencing an unknown selector token raises a ValueError.""" |
| 213 | + params = { |
| 214 | + "private_attribute_asset_cache": { |
| 215 | + "used_selectors": [ |
| 216 | + { |
| 217 | + "selector_id": "known-selector-id", |
| 218 | + "target_class": "Surface", |
| 219 | + "name": "known_selector", |
| 220 | + "children": [{"attribute": "name", "operator": "matches", "value": "wing*"}], |
| 221 | + } |
| 222 | + ] |
| 223 | + }, |
| 224 | + "model": { |
| 225 | + "selectors": [ |
| 226 | + "unknown-selector-id", # This token does not exist in used_selectors |
| 227 | + ] |
| 228 | + }, |
| 229 | + } |
| 230 | + |
| 231 | + db = EntityDictDatabase( |
| 232 | + surfaces=[ |
| 233 | + {"name": "wing_left", "private_attribute_entity_type_name": "Surface"}, |
| 234 | + ] |
| 235 | + ) |
| 236 | + |
| 237 | + with pytest.raises(ValueError, match="Selector token 'unknown-selector-id' not found"): |
| 238 | + expand_entity_selectors_in_place(db, params) |
0 commit comments