def handle_attribute( collection: Union[Dict[str, Any], List[Any]], cfg: dict, ) -> ResultE[MapValue]: """Handle one attribute with mappings, ifs, casting and default value. :param collection: The collection of data to find data in :type collection: Union[Dict[str, Any], List[Any]] :param configuration: :term:`configuration` data to use when mapping :type configuration: Dict[str, Any] :return: Success/Failure containers :rtype: MapValue configuration expected to look like this: .. code-block:: json { "mappings": [], # array of mapping objects "separator": None, "if_statements": [], # array of if statement objects "casting": {} # casting object, for casting types "default": "default value" } flow description: Map all objects in cfg[MAPPINGS] -> Apply separator to values if there are more than 1 Failure -> fix to Success(None) Apply if statements Success -> Cast Value Failure -> apply default value Return Result """ mapped_values = [ mapped.unwrap() for mapped in [ handle_mapping(collection, mapping) for mapping in cfg.get(MAPPINGS, []) ] if is_successful(mapped) ] # partially declare if statement and casting functions ifs = partial(apply_if_statements, if_objects=cfg.get(IF_STATEMENTS, [])) cast = partial(apply_casting, casting=cfg.get(CASTING, {})) return flow( apply_separator(mapped_values, separator=cfg.get(SEPARATOR, '')), fix(lambda _: None), # type: ignore bind(ifs), bind(cast), rescue(lambda _: apply_default(default=cfg.get(DEFAULT)), ), )
def test_separator(): """Test separator is applied between two values.""" test = [['val1', 'val2'], '-'] assert apply_separator(*test).unwrap() == 'val1-val2'
def test_no_separator(): """Test that no separator throws error.""" test = [['val1', 'val2'], None] with pytest.raises(UnwrapFailedError): apply_separator(*test).unwrap()
def test_no_value(): """When no value is given we should return Failure.""" test = [[], '-'] with pytest.raises(UnwrapFailedError): apply_separator(*test).unwrap()
def test_one_integer_value_with_other_value(): """Two values no matter the type should be cast to string.""" test = [[1, 'val2'], '-'] assert apply_separator(*test).unwrap() == '1-val2'
def test_one_integer_value_not_stringified(): """One value should allways return just the value uncasted.""" test = [[1], ''] assert apply_separator(*test).unwrap() == 1
def test_separator_one_value(): """Test when theres only one value, no separator should be applied.""" test = [['val1'], '-'] assert apply_separator(*test).unwrap() == 'val1'