def check_output_for_grouping(grouping): """ Check the behavior of a callback that returns the specified grouping """ outputs = make_dependency_grouping(grouping, Output) multi = not isinstance(outputs, Output) app = dash.Dash() mock_fn = mock.Mock() mock_fn.return_value = grouping wrapped_fn = app.callback( outputs, Input("input-a", "prop"), )(mock_fn) expected_outputs = [(dep.component_id, dep.component_property, val) for dep, val in zip(flatten_grouping(outputs), flatten_grouping(grouping))] outputs_list = [{ "id": out[0], "property": out[1] } for out in expected_outputs] if not multi: outputs_list = outputs_list[0] result = json.loads(wrapped_fn("Hello", outputs_list=outputs_list)) response = result["response"] for id, prop, val in expected_outputs: assert response[id][prop] == val
def test_flatten_odd_value(): # Anything other than tuple and dict should be treated as a # scalar and passed through expected = [0, sum, Input("foo", "bar")] vals_collection = (0, (sum, Input("foo", "bar"))) result = flatten_grouping(vals_collection) assert expected == result assert len(result) == grouping_len(vals_collection)
def test_flatten_dict_key_order(dict_grouping_size): grouping, size = dict_grouping_size expected = list(range(size)) # Reverse key order of value dict to make sure order is preserved rev_grouping = {k: grouping[k] for k in reversed(list(grouping.keys()))} result = flatten_grouping(rev_grouping, grouping) assert expected == result assert len(result) == grouping_len(grouping)
def test_map_grouping_mixed(mixed_grouping_size): grouping, size = mixed_grouping_size def fn(x): return x * 2 + 5 result = map_grouping(fn, grouping) expected = make_grouping_by_index( grouping, list(map(fn, flatten_grouping(grouping))) ) assert expected == result
def check_callback_inputs_for_grouping(grouping): """ Check the expected behavior of a callback function configured to input arguments according to the form of the provided grouping. If the grouping is a dict, then the callback function should be called with keyword arguments. Otherwise, it should be called with positional arguments """ inputs = make_dependency_grouping(grouping, [Input, State]) app = dash.Dash() mock_fn = mock.Mock() mock_fn.return_value = 23 app.callback( Output("output-a", "prop"), inputs, )(mock_fn) wrapped_fn = app.callback_map["output-a.prop"]["callback"] flat_input_state_values = flatten_grouping(grouping) flat_input_values = flat_input_state_values[0::2] flat_state_values = flat_input_state_values[1::2] flat_inputs = flat_input_values + flat_state_values json.loads( wrapped_fn(*flat_inputs, outputs_list={ "id": "output-a", "property": "prop" })) if isinstance(grouping, dict): # Check that user callback function was called with named keyword arguments mock_fn.assert_called_once_with(**grouping) elif isinstance(grouping, (tuple, list)): # Check that user callback function was called with positional arguments mock_fn.assert_called_once_with(*grouping) else: # Check that user callback function was called with single argument mock_fn.assert_called_once_with(grouping)
def test_flatten_mixed(mixed_grouping_size): grouping, size = mixed_grouping_size expected = list(range(size)) result = flatten_grouping(grouping) assert expected == result assert len(result) == grouping_len(grouping)
def test_flatten_scalar(scalar_grouping_size): grouping, size = scalar_grouping_size expected = list(range(size)) result = flatten_grouping(grouping) assert expected == result assert len(result) == grouping_len(grouping)