(parameters: Dict,)
return utils.gen_cartesian_product(*parsed_parameters_list)
parse parameters and generate cartesian product.

    Args:
        parameters (Dict) parameters: parameter name and value mapping
            parameter value may be in three types:
                (1) data list, e.g. ["iOS/10.1", "iOS/10.2", "iOS/10.3"]
                (2) call built-in parameterize function, "${parameterize(account.csv)}"
                (3) call custom function in debugtalk.py, "${gen_app_version()}"

    Returns:
        list: cartesian product list

    Examples:
        >>> parameters = {
            "user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"],
            "username-password": "${parameterize(account.csv)}",
            "app_version": "${gen_app_version()}",
        }
        >>> parse_parameters(parameters)
parse parameters and generate cartesian product.
parse parameters and generate cartesian product .
def parse_parameters(parameters: Dict,) -> List[Dict]:
    """ parse parameters and generate cartesian product.

    Args:
        parameters (Dict) parameters: parameter name and value mapping
            parameter value may be in three types:
                (1) data list, e.g. ["iOS/10.1", "iOS/10.2", "iOS/10.3"]
                (2) call built-in parameterize function, "${parameterize(account.csv)}"
                (3) call custom function in debugtalk.py, "${gen_app_version()}"

    Returns:
        list: cartesian product list

    Examples:
        >>> parameters = {
            "user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"],
            "username-password": "${parameterize(account.csv)}",
            "app_version": "${gen_app_version()}",
        }
        >>> parse_parameters(parameters)

    """
    parsed_parameters_list: List[List[Dict]] = []

    # load project_meta functions
    project_meta = loader.load_project_meta(os.getcwd())
    functions_mapping = project_meta.functions

    for parameter_name, parameter_content in parameters.items():
        parameter_name_list = parameter_name.split("-")

        if isinstance(parameter_content, List):
            # (1) data list
            # e.g. {"app_version": ["2.8.5", "2.8.6"]}
            #       => [{"app_version": "2.8.5", "app_version": "2.8.6"}]
            # e.g. {"username-password": [["user1", "111111"], ["test2", "222222"]}
            #       => [{"username": "user1", "password": "111111"}, {"username": "user2", "password": "222222"}]
            parameter_content_list: List[Dict] = []
            for parameter_item in parameter_content:
                if not isinstance(parameter_item, (list, tuple)):
                    # "2.8.5" => ["2.8.5"]
                    parameter_item = [parameter_item]

                # ["app_version"], ["2.8.5"] => {"app_version": "2.8.5"}
                # ["username", "password"], ["user1", "111111"] => {"username": "user1", "password": "111111"}
                parameter_content_dict = dict(zip(parameter_name_list, parameter_item))
                parameter_content_list.append(parameter_content_dict)

        elif isinstance(parameter_content, Text):
            # (2) & (3)
            parsed_parameter_content: List = parse_data(
                parameter_content, {}, functions_mapping
            )
            if not isinstance(parsed_parameter_content, List):
                raise exceptions.ParamsError(
                    f"parameters content should be in List type, got {parsed_parameter_content} for {parameter_content}"
                )

            parameter_content_list: List[Dict] = []
            for parameter_item in parsed_parameter_content:
                if isinstance(parameter_item, Dict):
                    # get subset by parameter name
                    # {"app_version": "${gen_app_version()}"}
                    # gen_app_version() => [{'app_version': '2.8.5'}, {'app_version': '2.8.6'}]
                    # {"username-password": "${get_account()}"}
                    # get_account() => [
                    #       {"username": "user1", "password": "111111"},
                    #       {"username": "user2", "password": "222222"}
                    # ]
                    parameter_dict: Dict = {
                        key: parameter_item[key] for key in parameter_name_list
                    }
                elif isinstance(parameter_item, (List, tuple)):
                    if len(parameter_name_list) == len(parameter_item):
                        # {"username-password": "${get_account()}"}
                        # get_account() => [("user1", "111111"), ("user2", "222222")]
                        parameter_dict = dict(zip(parameter_name_list, parameter_item))
                    else:
                        raise exceptions.ParamsError(
                            f"parameter names length are not equal to value length.\n"
                            f"parameter names: {parameter_name_list}\n"
                            f"parameter values: {parameter_item}"
                        )
                elif len(parameter_name_list) == 1:
                    # {"user_agent": "${get_user_agent()}"}
                    # get_user_agent() => ["iOS/10.1", "iOS/10.2"]
                    # parameter_dict will get: {"user_agent": "iOS/10.1", "user_agent": "iOS/10.2"}
                    parameter_dict = {parameter_name_list[0]: parameter_item}
                else:
                    raise exceptions.ParamsError(
                        f"Invalid parameter names and values:\n"
                        f"parameter names: {parameter_name_list}\n"
                        f"parameter values: {parameter_item}"
                    )

                parameter_content_list.append(parameter_dict)

        else:
            raise exceptions.ParamsError(
                f"parameter content should be List or Text(variables or functions call), got {parameter_content}"
            )

        parsed_parameters_list.append(parameter_content_list)

    return utils.gen_cartesian_product(*parsed_parameters_list)
def parse_parameters ( parameters : Dict , ) -> List [ Dict ] : parsed_parameters_list : List [ List [ Dict ] ] = [ ] # load project_meta functions project_meta = loader . load_project_meta ( os . getcwd ( ) ) functions_mapping = project_meta . functions for parameter_name , parameter_content in parameters . items ( ) : parameter_name_list = parameter_name . split ( "-" ) if isinstance ( parameter_content , List ) : # (1) data list # e.g. {"app_version": ["2.8.5", "2.8.6"]} #       => [{"app_version": "2.8.5", "app_version": "2.8.6"}] # e.g. {"username-password": [["user1", "111111"], ["test2", "222222"]} #       => [{"username": "user1", "password": "111111"}, {"username": "user2", "password": "222222"}] parameter_content_list : List [ Dict ] = [ ] for parameter_item in parameter_content : if not isinstance ( parameter_item , ( list , tuple ) ) : # "2.8.5" => ["2.8.5"] parameter_item = [ parameter_item ] # ["app_version"], ["2.8.5"] => {"app_version": "2.8.5"} # ["username", "password"], ["user1", "111111"] => {"username": "user1", "password": "111111"} parameter_content_dict = dict ( zip ( parameter_name_list , parameter_item ) ) parameter_content_list . append ( parameter_content_dict ) elif isinstance ( parameter_content , Text ) : # (2) & (3) parsed_parameter_content : List = parse_data ( parameter_content , { } , functions_mapping ) if not isinstance ( parsed_parameter_content , List ) : raise exceptions . ParamsError ( f"parameters content should be in List type, got {parsed_parameter_content} for {parameter_content}" ) parameter_content_list : List [ Dict ] = [ ] for parameter_item in parsed_parameter_content : if isinstance ( parameter_item , Dict ) : # get subset by parameter name # {"app_version": "${gen_app_version()}"} # gen_app_version() => [{'app_version': '2.8.5'}, {'app_version': '2.8.6'}] # {"username-password": "${get_account()}"} # get_account() => [ #       {"username": "user1", "password": "111111"}, #       {"username": "user2", "password": "222222"} # ] parameter_dict : Dict = { key : parameter_item [ key ] for key in parameter_name_list } elif isinstance ( parameter_item , ( List , tuple ) ) : if len ( parameter_name_list ) == len ( parameter_item ) : # {"username-password": "${get_account()}"} # get_account() => [("user1", "111111"), ("user2", "222222")] parameter_dict = dict ( zip ( parameter_name_list , parameter_item ) ) else : raise exceptions . ParamsError ( f"parameter names length are not equal to value length.\n" f"parameter names: {parameter_name_list}\n" f"parameter values: {parameter_item}" ) elif len ( parameter_name_list ) == 1 : # {"user_agent": "${get_user_agent()}"} # get_user_agent() => ["iOS/10.1", "iOS/10.2"] # parameter_dict will get: {"user_agent": "iOS/10.1", "user_agent": "iOS/10.2"} parameter_dict = { parameter_name_list [ 0 ] : parameter_item } else : raise exceptions . ParamsError ( f"Invalid parameter names and values:\n" f"parameter names: {parameter_name_list}\n" f"parameter values: {parameter_item}" ) parameter_content_list . append ( parameter_dict ) else : raise exceptions . ParamsError ( f"parameter content should be List or Text(variables or functions call), got {parameter_content}" ) parsed_parameters_list . append ( parameter_content_list ) return utils . gen_cartesian_product ( * parsed_parameters_list )