Skip to content

Commit 5ee26d0

Browse files
committed
Add test_targets_for_data_frame_parameter and fixing the code
1 parent ce87a2f commit 5ee26d0

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

vizro-core/src/vizro/models/_controls/parameter.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from vizro._constants import PARAMETER_ACTION_PREFIX
77
from vizro.actions import _parameter
88
from vizro.managers import model_manager
9+
from vizro.managers._model_manager import ModelID
910
from vizro.models import Action, VizroBaseModel
1011
from vizro.models._components.form import Checklist, DatePicker, Dropdown, RadioItems, RangeSlider, Slider
1112
from vizro.models._models_utils import _log_call
@@ -115,7 +116,8 @@ def _set_actions(self):
115116
if filter._dynamic
116117
]
117118

118-
filter_targets = set()
119+
existing_target_ids: set[ModelID] = {cast(ModelID, target.split(".")[0]) for target in self.targets}
120+
additional_targets: set[ModelID] = set()
119121

120122
# Extend parameter targets with dynamic filters linked to the same figure.
121123
# Also, include dynamic filter targets to ensure new filter options are correctly calculated
@@ -125,10 +127,11 @@ def _set_actions(self):
125127
if figure_arg.startswith("data_frame"):
126128
for filter in page_dynamic_filters:
127129
if figure_id in filter.targets:
128-
filter_targets.add(filter.id)
129-
filter_targets |= set(filter.targets)
130+
additional_targets.add(cast(ModelID, filter.id))
131+
# Exclude existing targets defined with the "dot" notation to avoid duplicates
132+
additional_targets |= set(filter.targets) - existing_target_ids
130133

131-
self.targets.extend(list(filter_targets))
134+
self.targets.extend(list(additional_targets))
132135

133136
self.selector.actions = [
134137
Action(id=f"{PARAMETER_ACTION_PREFIX}_{self.id}", function=_parameter(targets=self.targets))

vizro-core/tests/unit/vizro/models/_controls/test_parameter.py

+34-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from asserts import assert_component_equal
33

44
import vizro.models as vm
5-
from vizro.managers import model_manager
5+
from vizro.managers import data_manager, model_manager
66
from vizro.models._action._actions_chain import ActionsChain
77
from vizro.models._controls.parameter import Parameter
88
from vizro.models.types import CapturedCallable
@@ -52,8 +52,8 @@ def test_duplicate_parameter_target_failed_two_params(self):
5252
Parameter(targets=["scatter_chart.x"], selector=vm.Dropdown(options=["lifeExp", "pop"]))
5353

5454

55-
@pytest.mark.usefixtures("managers_one_page_two_graphs")
5655
class TestPreBuildMethod:
56+
@pytest.mark.usefixtures("managers_one_page_two_graphs")
5757
@pytest.mark.parametrize(
5858
"test_input, title",
5959
[
@@ -73,6 +73,7 @@ def test_set_target_and_title_valid(self, test_input, title):
7373
assert parameter.targets == ["scatter_chart.x"]
7474
assert parameter.selector.title == title
7575

76+
@pytest.mark.usefixtures("managers_one_page_two_graphs")
7677
@pytest.mark.parametrize("test_input", [vm.Slider(), vm.RangeSlider(), vm.DatePicker()])
7778
def test_numerical_and_temporal_selectors_missing_values(self, test_input):
7879
parameter = Parameter(targets=["scatter_chart.x"], selector=test_input)
@@ -83,6 +84,7 @@ def test_numerical_and_temporal_selectors_missing_values(self, test_input):
8384
):
8485
parameter.pre_build()
8586

87+
@pytest.mark.usefixtures("managers_one_page_two_graphs")
8688
@pytest.mark.parametrize("test_input", [vm.Checklist(), vm.Dropdown(), vm.RadioItems()])
8789
def test_categorical_selectors_with_missing_options(self, test_input):
8890
parameter = Parameter(targets=["scatter_chart.x"], selector=test_input)
@@ -93,6 +95,7 @@ def test_categorical_selectors_with_missing_options(self, test_input):
9395
):
9496
parameter.pre_build()
9597

98+
@pytest.mark.usefixtures("managers_one_page_two_graphs")
9699
@pytest.mark.parametrize(
97100
"test_input",
98101
[
@@ -111,6 +114,35 @@ def test_set_actions(self, test_input):
111114
assert isinstance(default_action.actions[0].function, CapturedCallable)
112115
assert default_action.actions[0].id == f"parameter_action_{parameter.id}"
113116

117+
@pytest.mark.usefixtures("managers_one_page_two_graphs_with_dynamic_data")
118+
@pytest.mark.parametrize(
119+
"filter_targets, expected_parameter_targets",
120+
[
121+
([], {"scatter_chart.data_frame.first_n"}),
122+
(["scatter_chart"], {"scatter_chart.data_frame.first_n", "filter_id"}),
123+
(["scatter_chart", "box_chart"], {"scatter_chart.data_frame.first_n", "filter_id", "box_chart"}),
124+
],
125+
)
126+
def test_targets_for_data_frame_parameter(
127+
self, filter_targets, expected_parameter_targets, gapminder_dynamic_first_n_last_n_function
128+
):
129+
data_manager["gapminder_dynamic_first_n_last_n"] = gapminder_dynamic_first_n_last_n_function
130+
131+
if filter_targets:
132+
dynamic_filter = vm.Filter(id="filter_id", column="pop", targets=filter_targets)
133+
model_manager["test_page"].controls.append(dynamic_filter)
134+
dynamic_filter.pre_build()
135+
136+
data_frame_parameter = vm.Parameter(
137+
id="test_data_frame_parameter",
138+
targets=["scatter_chart.data_frame.first_n"],
139+
selector=vm.Slider(id="first_n_parameter", min=1, max=10, step=1),
140+
)
141+
model_manager["test_page"].controls.append(data_frame_parameter)
142+
data_frame_parameter.pre_build()
143+
144+
assert set(data_frame_parameter.targets) == expected_parameter_targets
145+
114146

115147
@pytest.mark.usefixtures("managers_one_page_two_graphs")
116148
class TestParameterBuild:

0 commit comments

Comments
 (0)