chrome/test/webapps/file_reading.py
def read_actions_file(
        actions_csv_file,
        supported_platform_actions: PartialAndFullCoverageByBaseName
) -> Tuple[ActionsByName, Dict[str, str]]:
    """Reads the actions comma-separated-values file.

    If modes are specified for an action in the file, then one action is
    added to the results dictionary per action_base_name + mode
    parameterized. A mode marked with a "*" is considered the default
    mode for that action.

    If output actions are specified for an action, then it will be a
    PARAMETERIZED action and the output actions will be resolved into the
    `Action.output_actions` field.

    See the README.md for more information about actions and action templates.

    Args:
        actions_csv_file: The comma-separated-values file read to parse all
                          actions.
        supported_platform_actions: A dictionary of platform to the actions that
                                    are fully or partially covered on that
                                    platform.

    Returns (actions_by_name,
             action_base_name_to_default_mode):
        actions_by_name:
            Index of all actions by action name.
        action_base_name_to_default_mode:
            Index of action base names to the default mode. Only populated
            for actions with default modes.

    Raises:
        ValueError: The input file is invalid.
    """
    actions_by_name: Dict[str, Action] = {}
    action_base_name_to_default_mode: Dict[str, str] = {}
    action_base_names: Set[str] = set()
    all_output_action_names: List[str] = []
    all_short_name: Set[str] = set()
    for i, row in enumerate(actions_csv_file):
        if not row:
            continue
        if row[0].startswith("#"):
            continue
        if len(row) < MIN_COLUMNS_ACTIONS_FILE:
            raise ValueError(f"Row {i!r} does not contain enough entries. "
                             f"Got {row}.")
        if row[8] == "Abandoned":
            continue

        action_base_name = row[0].strip()
        action_base_names.add(action_base_name)
        if not re.fullmatch(r'[a-z_]+', action_base_name):
            raise ValueError(f"Invald action base name {action_base_name} on "
                             f"row {i!r}. Please use snake_case.")
        short_name_base = row[3].strip()
        if not short_name_base or short_name_base in all_short_name:
            raise ValueError(
                f"Short name '{short_name_base}' on line {i!r} is "
                f"not populated or already used.")

        type = ActionType.STATE_CHANGE
        if action_base_name.startswith("check_"):
            type = ActionType.STATE_CHECK

        output_action_names = []
        output_actions_str = row[2].strip()
        if output_actions_str:
            type = ActionType.PARAMETERIZED
            # Output actions for parameterized actions can also specify (or
            # assume default) action modes (e.g. `do_action(Mode1)`) if the
            # parameterized action doesn't have a mode. However, they cannot be
            # fully resolved yet without reading all actions. So the resolution
            # must happen later.
            output_action_names = [
                output.strip() for output in output_actions_str.split("&")
            ]
            # Keep track of all specified output actions for error checking.
            # Resolve any parameters if they are specified.
            all_output_action_names.extend([
                name.replace("(", "_").rstrip(")")
                for name in output_action_names
            ])

        (partially_supported_platforms,
         fully_supported_platforms) = supported_platform_actions.get(
             action_base_name, (set(), set()))

        modes = [mode.strip() for mode in row[1].split("|")]
        if not modes:
            modes = [""]
        for mode in modes:
            if not re.fullmatch(r'([A-Z]\w*\*?)|', mode):
                raise ValueError(f"Invald action mode name {mode!r}) on row "
                                 f"{i!r}. Please use PascalCase.")
            if "*" in mode:
                action_base_name_to_default_mode[
                    action_base_name] = mode.rstrip("*")
            mode = mode.rstrip("*")
            name = action_base_name
            # Convert the `cpp_method` to Pascal-case
            cpp_method = ''.join(word.title()
                                 for word in action_base_name.split('_'))
            output_action_names_with_mode: List[str] = []
            short_name: str = ""
            if mode != "":
                # If the action has a real mode, then modify the name, short
                # name, output actions, and cpp method.
                name += "_" + mode
                short_name = short_name_base + mode
                output_action_names_with_mode = [
                    action_name + "_" + mode
                    for action_name in output_action_names
                ]
                cpp_method += "(\"" + mode + "\")"
            else:
                output_action_names_with_mode = output_action_names
                short_name = short_name_base
                cpp_method += "()"
            if name in actions_by_name:
                raise ValueError(f"Cannot add duplicate action {name} on row "
                                 f"{i!r}")

            action = Action(name, action_base_name, short_name, cpp_method,
                            type, fully_supported_platforms,
                            partially_supported_platforms)
            all_short_name.add(short_name)
            if output_action_names_with_mode:
                action._output_action_names = output_action_names_with_mode
            actions_by_name[action.name] = action

    unused_supported_actions = set(
        supported_platform_actions.keys()).difference(action_base_names)
    if unused_supported_actions:
        raise ValueError(f"Actions specified as suppored that are not in "
                         f"the actions list: {unused_supported_actions}.")

    # Filter out empty strings from the output_action_base_names.
    all_output_action_names = list(filter(len, all_output_action_names))
    # Make sure all output actions are either resolvable or are base names.
    for output_action_name in all_output_action_names:
        if (output_action_name not in actions_by_name
                and output_action_name not in action_base_names):
            raise ValueError(f"Could not find action for "
                             f"specified output action {output_action_name}.")
    # Resolve the output actions
    for action in actions_by_name.values():
        if action.type is not ActionType.PARAMETERIZED:
            continue
        assert (action._output_action_names)
        for output_action_name in action._output_action_names:
            # Output actions can specify a mode or assume default action modes
            # if the parameterized action doesn't have a mode.
            canonical_name = human_friendly_name_to_canonical_action_name(
                output_action_name, action_base_name_to_default_mode)
            if canonical_name in actions_by_name:
                action.output_actions.append(actions_by_name[canonical_name])
            else:
                # Having this lookup fail is a feature, it allows a
                # parameterized action to reference output actions that might
                # not all support every mode of the parameterized action. When
                # that mode is specified in a test case, then that action would
                # be excluded & one less test case would be generated.
                logging.info(f"Output action {canonical_name} not found for "
                             f"parameterized action {action.name}.")
        assert (action.output_actions)
    return (actions_by_name, action_base_name_to_default_mode)
Reads the actions comma-separated-values file.

    If modes are specified for an action in the file, then one action is
    added to the results dictionary per action_base_name + mode
    parameterized. A mode marked with a "*" is considered the default
    mode for that action.

    If output actions are specified for an action, then it will be a
    PARAMETERIZED action and the output actions will be resolved into the
    `Action.output_actions` field.

    See the README.md for more information about actions and action templates.

    Args:
        actions_csv_file: The comma-separated-values file read to parse all
                          actions.
        supported_platform_actions: A dictionary of platform to the actions that
                                    are fully or partially covered on that
                                    platform.

    Returns (actions_by_name,
             action_base_name_to_default_mode):
        actions_by_name:
            Index of all actions by action name.
        action_base_name_to_default_mode:
            Index of action base names to the default mode. Only populated
            for actions with default modes.

    Raises:
        ValueError: The input file is invalid.
    
Reads the actions comma-separated-values file.
If modes are specified for an action in the file, then one action is
added to the results dictionary per action_base_name + mode
parameterized. A mode marked with a "*" is considered the default
mode for that action.

If output actions are specified for an action, then it will be a
PARAMETERIZED action and the output actions will be resolved into the
`Action.output_actions` field.

See the README.md for more information about actions and action templates.
Reads the actions comma - separated - values file . If modes are specified for an action in the file then one action is added to the results dictionary per action_base_name + mode parameterized . A mode marked with a " * " is considered the default mode for that action . If output actions are specified for an action then it will be a PARAMETERIZED action and the output actions will be resolved into the ` Action . output_actions ` field . See the README . md for more information about actions and action templates .
def read_actions_file(
        actions_csv_file,
        supported_platform_actions: PartialAndFullCoverageByBaseName
) -> Tuple[ActionsByName, Dict[str, str]]:
    actions_by_name: Dict[str, Action] = {}
    action_base_name_to_default_mode: Dict[str, str] = {}
    action_base_names: Set[str] = set()
    all_output_action_names: List[str] = []
    all_short_name: Set[str] = set()
    for i, row in enumerate(actions_csv_file):
        if not row:
            continue
        if row[0].startswith("#"):
            continue
        if len(row) < MIN_COLUMNS_ACTIONS_FILE:
            raise ValueError(f"Row {i!r} does not contain enough entries. "
                             f"Got {row}.")
        if row[8] == "Abandoned":
            continue
        action_base_name = row[0].strip()
        action_base_names.add(action_base_name)
        if not re.fullmatch(r'[a-z_]+', action_base_name):
            raise ValueError(f"Invald action base name {action_base_name} on "
                             f"row {i!r}. Please use snake_case.")
        short_name_base = row[3].strip()
        if not short_name_base or short_name_base in all_short_name:
            raise ValueError(
                f"Short name '{short_name_base}' on line {i!r} is "
                f"not populated or already used.")
        type = ActionType.STATE_CHANGE
        if action_base_name.startswith("check_"):
            type = ActionType.STATE_CHECK
        output_action_names = []
        output_actions_str = row[2].strip()
        if output_actions_str:
            type = ActionType.PARAMETERIZED
            output_action_names = [
                output.strip() for output in output_actions_str.split("&")
            ]
            all_output_action_names.extend([
                name.replace("(", "_").rstrip(")")
                for name in output_action_names
            ])
        (partially_supported_platforms,
         fully_supported_platforms) = supported_platform_actions.get(
             action_base_name, (set(), set()))
        modes = [mode.strip() for mode in row[1].split("|")]
        if not modes:
            modes = [""]
        for mode in modes:
            if not re.fullmatch(r'([A-Z]\w*\*?)|', mode):
                raise ValueError(f"Invald action mode name {mode!r}) on row "
                                 f"{i!r}. Please use PascalCase.")
            if "*" in mode:
                action_base_name_to_default_mode[
                    action_base_name] = mode.rstrip("*")
            mode = mode.rstrip("*")
            name = action_base_name
            cpp_method = ''.join(word.title()
                                 for word in action_base_name.split('_'))
            output_action_names_with_mode: List[str] = []
            short_name: str = ""
            if mode != "":
                name += "_" + mode
                short_name = short_name_base + mode
                output_action_names_with_mode = [
                    action_name + "_" + mode
                    for action_name in output_action_names
                ]
                cpp_method += "(\"" + mode + "\")"
            else:
                output_action_names_with_mode = output_action_names
                short_name = short_name_base
                cpp_method += "()"
            if name in actions_by_name:
                raise ValueError(f"Cannot add duplicate action {name} on row "
                                 f"{i!r}")
            action = Action(name, action_base_name, short_name, cpp_method,
                            type, fully_supported_platforms,
                            partially_supported_platforms)
            all_short_name.add(short_name)
            if output_action_names_with_mode:
                action._output_action_names = output_action_names_with_mode
            actions_by_name[action.name] = action
    unused_supported_actions = set(
        supported_platform_actions.keys()).difference(action_base_names)
    if unused_supported_actions:
        raise ValueError(f"Actions specified as suppored that are not in "
                         f"the actions list: {unused_supported_actions}.")
    all_output_action_names = list(filter(len, all_output_action_names))
    for output_action_name in all_output_action_names:
        if (output_action_name not in actions_by_name
                and output_action_name not in action_base_names):
            raise ValueError(f"Could not find action for "
                             f"specified output action {output_action_name}.")
    for action in actions_by_name.values():
        if action.type is not ActionType.PARAMETERIZED:
            continue
        assert (action._output_action_names)
        for output_action_name in action._output_action_names:
            canonical_name = human_friendly_name_to_canonical_action_name(
                output_action_name, action_base_name_to_default_mode)
            if canonical_name in actions_by_name:
                action.output_actions.append(actions_by_name[canonical_name])
            else:
                logging.info(f"Output action {canonical_name} not found for "
                             f"parameterized action {action.name}.")
        assert (action.output_actions)
    return (actions_by_name, action_base_name_to_default_mode)
def read_actions_file ( actions_csv_file , supported_platform_actions : PartialAndFullCoverageByBaseName ) -> Tuple [ ActionsByName , Dict [ str , str ] ] : actions_by_name : Dict [ str , Action ] = { } action_base_name_to_default_mode : Dict [ str , str ] = { } action_base_names : Set [ str ] = set ( ) all_output_action_names : List [ str ] = [ ] all_short_name : Set [ str ] = set ( ) for i , row in enumerate ( actions_csv_file ) : if not row : continue if row [ 0 ] . startswith ( "#" ) : continue if len ( row ) < MIN_COLUMNS_ACTIONS_FILE : raise ValueError ( f"Row {i!r} does not contain enough entries. " f"Got {row}." ) if row [ 8 ] == "Abandoned" : continue action_base_name = row [ 0 ] . strip ( ) action_base_names . add ( action_base_name ) if not re . fullmatch ( r'[a-z_]+' , action_base_name ) : raise ValueError ( f"Invald action base name {action_base_name} on " f"row {i!r}. Please use snake_case." ) short_name_base = row [ 3 ] . strip ( ) if not short_name_base or short_name_base in all_short_name : raise ValueError ( f"Short name '{short_name_base}' on line {i!r} is " f"not populated or already used." ) type = ActionType . STATE_CHANGE if action_base_name . startswith ( "check_" ) : type = ActionType . STATE_CHECK output_action_names = [ ] output_actions_str = row [ 2 ] . strip ( ) if output_actions_str : type = ActionType . PARAMETERIZED output_action_names = [ output . strip ( ) for output in output_actions_str . split ( "&" ) ] all_output_action_names . extend ( [ name . replace ( "(" , "_" ) . rstrip ( ")" ) for name in output_action_names ] ) ( partially_supported_platforms , fully_supported_platforms ) = supported_platform_actions . get ( action_base_name , ( set ( ) , set ( ) ) ) modes = [ mode . strip ( ) for mode in row [ 1 ] . split ( "|" ) ] if not modes : modes = [ "" ] for mode in modes : if not re . fullmatch ( r'([A-Z]\w*\*?)|' , mode ) : raise ValueError ( f"Invald action mode name {mode!r}) on row " f"{i!r}. Please use PascalCase." ) if "*" in mode : action_base_name_to_default_mode [ action_base_name ] = mode . rstrip ( "*" ) mode = mode . rstrip ( "*" ) name = action_base_name cpp_method = '' . join ( word . title ( ) for word in action_base_name . split ( '_' ) ) output_action_names_with_mode : List [ str ] = [ ] short_name : str = "" if mode != "" : name += "_" + mode short_name = short_name_base + mode output_action_names_with_mode = [ action_name + "_" + mode for action_name in output_action_names ] cpp_method += "(\"" + mode + "\")" else : output_action_names_with_mode = output_action_names short_name = short_name_base cpp_method += "()" if name in actions_by_name : raise ValueError ( f"Cannot add duplicate action {name} on row " f"{i!r}" ) action = Action ( name , action_base_name , short_name , cpp_method , type , fully_supported_platforms , partially_supported_platforms ) all_short_name . add ( short_name ) if output_action_names_with_mode : action . _output_action_names = output_action_names_with_mode actions_by_name [ action . name ] = action unused_supported_actions = set ( supported_platform_actions . keys ( ) ) . difference ( action_base_names ) if unused_supported_actions : raise ValueError ( f"Actions specified as suppored that are not in " f"the actions list: {unused_supported_actions}." ) all_output_action_names = list ( filter ( len , all_output_action_names ) ) for output_action_name in all_output_action_names : if ( output_action_name not in actions_by_name and output_action_name not in action_base_names ) : raise ValueError ( f"Could not find action for " f"specified output action {output_action_name}." ) for action in actions_by_name . values ( ) : if action . type is not ActionType . PARAMETERIZED : continue assert ( action . _output_action_names ) for output_action_name in action . _output_action_names : canonical_name = human_friendly_name_to_canonical_action_name ( output_action_name , action_base_name_to_default_mode ) if canonical_name in actions_by_name : action . output_actions . append ( actions_by_name [ canonical_name ] ) else : logging . info ( f"Output action {canonical_name} not found for " f"parameterized action {action.name}." ) assert ( action . output_actions ) return ( actions_by_name , action_base_name_to_default_mode )
Reads the actions comma-separated-values file.
Reads the actions comma - separated - values file .
"""Reads the actions comma-separated-values file.

    If modes are specified for an action in the file, then one action is
    added to the results dictionary per action_base_name + mode
    parameterized. A mode marked with a "*" is considered the default
    mode for that action.

    If output actions are specified for an action, then it will be a
    PARAMETERIZED action and the output actions will be resolved into the
    `Action.output_actions` field.

    See the README.md for more information about actions and action templates.

    Args:
        actions_csv_file: The comma-separated-values file read to parse all
                          actions.
        supported_platform_actions: A dictionary of platform to the actions that
                                    are fully or partially covered on that
                                    platform.

    Returns (actions_by_name,
             action_base_name_to_default_mode):
        actions_by_name:
            Index of all actions by action name.
        action_base_name_to_default_mode:
            Index of action base names to the default mode. Only populated
            for actions with default modes.

    Raises:
        ValueError: The input file is invalid.
    """ # Output actions for parameterized actions can also specify (or # assume default) action modes (e.g. `do_action(Mode1)`) if the # parameterized action doesn't have a mode. However, they cannot be # fully resolved yet without reading all actions. So the resolution # must happen later. # Keep track of all specified output actions for error checking. # Resolve any parameters if they are specified. # Convert the `cpp_method` to Pascal-case # If the action has a real mode, then modify the name, short # name, output actions, and cpp method. # Filter out empty strings from the output_action_base_names. # Make sure all output actions are either resolvable or are base names. # Resolve the output actions # Output actions can specify a mode or assume default action modes # if the parameterized action doesn't have a mode. # Having this lookup fail is a feature, it allows a # parameterized action to reference output actions that might # not all support every mode of the parameterized action. When # that mode is specified in a test case, then that action would # be excluded & one less test case would be generated.
The input file is invalid.
The input file is invalid .
ValueError
actions_csv_file
The comma-separated-values file read to parse all
actions.
The comma - separated - values file read to parse all actions .
supported_platform_actions
PartialAndFullCoverageByBaseName
A dictionary of platform to the actions that
are fully or partially covered on that
platform.
A dictionary of platform to the actions that are fully or partially covered on that platform .