Skip to content

Commit

Permalink
Refactoring: move keyword matches to model.py
Browse files Browse the repository at this point in the history
  • Loading branch information
HardNorth committed Jan 10, 2025
1 parent dfbe52e commit 7cc9747
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 69 deletions.
65 changes: 1 addition & 64 deletions robotframework_reportportal/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
import binascii
import fnmatch
import re
from abc import ABC, abstractmethod
from typing import Callable, Iterable, Optional, Tuple

from robotframework_reportportal.model import Keyword
from typing import Iterable, Optional, Tuple


def translate_glob_to_regex(pattern: Optional[str]) -> Optional[re.Pattern]:
Expand Down Expand Up @@ -51,66 +48,6 @@ def match_pattern(pattern: Optional[re.Pattern], line: Optional[str]) -> bool:
return pattern.fullmatch(line) is not None


class KeywordMatch(ABC):
"""Base class for keyword matchers."""

@abstractmethod
def match(self, kw: Keyword) -> bool:
"""Check if the keyword matches the criteria."""


class KeywordEqual(KeywordMatch):
"""Match keyword based on a predicate."""

predicate: Callable[[Keyword], bool]

def __init__(self, predicate: Callable[[Keyword], bool] = None) -> None:
"""Initialize the matcher with the predicate."""
self.predicate = predicate

def match(self, kw: Keyword) -> bool:
"""Check if the keyword matches the criteria."""
return self.predicate(kw)


class KeywordNameMatch(KeywordEqual):
"""Match keyword based on the name pattern."""

def __init__(self, pattern: Optional[str]) -> None:
"""Initialize the matcher with the pattern."""
super().__init__(lambda kw: match_pattern(pattern, kw.name))


class KeywordTypeEqual(KeywordEqual):
"""Match keyword based on the type."""

def __init__(self, expected_value: Optional[str]) -> None:
"""Initialize the matcher with the expected value."""
super().__init__(lambda kw: kw.keyword_type == expected_value)


class KeywordTagMatch(KeywordMatch):
"""Match keyword based on the tag pattern."""

pattern: Optional[re.Pattern]

def __init__(self, pattern: Optional[str]) -> None:
"""Initialize the matcher with the pattern."""
self.pattern = translate_glob_to_regex(pattern)

def match(self, kw: Keyword) -> bool:
"""Check if the keyword matches the criteria."""
return next((True for t in kw.tags if match_pattern(self.pattern, t)), False)


class KeywordStatusEqual(KeywordEqual):
"""Match keyword based on the status."""

def __init__(self, status: str) -> None:
"""Initialize the matcher with the status."""
super().__init__(lambda kw: kw.status == status)


def replace_patterns(text: str, patterns: Iterable[Tuple[re.Pattern, str]]) -> str:
"""Replace given patterns in the text."""
result = text
Expand Down
11 changes: 8 additions & 3 deletions robotframework_reportportal/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,19 @@

from reportportal_client.helpers import LifoQueue, guess_content_type_from_bytes, is_binary

from robotframework_reportportal.helpers import (
from robotframework_reportportal.helpers import _unescape
from robotframework_reportportal.model import (
Entity,
Keyword,
KeywordMatch,
KeywordNameMatch,
KeywordTagMatch,
KeywordTypeEqual,
_unescape,
Launch,
LogMessage,
Suite,
Test,
)
from robotframework_reportportal.model import Entity, Keyword, Launch, LogMessage, Suite, Test
from robotframework_reportportal.service import RobotService
from robotframework_reportportal.static import MAIN_SUITE_ID, PABOT_WITHOUT_LAUNCH_ID_MSG
from robotframework_reportportal.variables import Variables
Expand Down
66 changes: 64 additions & 2 deletions robotframework_reportportal/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
"""This module contains models representing Robot Framework test items."""

import os
from typing import Any, Dict, List, Optional, Union
import re
from abc import ABC, abstractmethod
from typing import Any, Callable, Dict, List, Optional, Union

from reportportal_client.helpers import gen_attributes

from robotframework_reportportal.helpers import robot_markup_to_markdown
from robotframework_reportportal.helpers import match_pattern, robot_markup_to_markdown, translate_glob_to_regex

TEST_CASE_ID_SIGN = "test_case_id:"

Expand Down Expand Up @@ -332,3 +334,63 @@ def update(self, attributes: Dict[str, Any]) -> "Test":
self.message = attributes.get("message")
self.status = attributes.get("status")
return self


class KeywordMatch(ABC):
"""Base class for keyword matchers."""

@abstractmethod
def match(self, kw: Keyword) -> bool:
"""Check if the keyword matches the criteria."""


class KeywordEqual(KeywordMatch):
"""Match keyword based on a predicate."""

predicate: Callable[[Keyword], bool]

def __init__(self, predicate: Callable[[Keyword], bool] = None) -> None:
"""Initialize the matcher with the predicate."""
self.predicate = predicate

def match(self, kw: Keyword) -> bool:
"""Check if the keyword matches the criteria."""
return self.predicate(kw)


class KeywordNameMatch(KeywordEqual):
"""Match keyword based on the name pattern."""

def __init__(self, pattern: Optional[str]) -> None:
"""Initialize the matcher with the pattern."""
super().__init__(lambda kw: match_pattern(pattern, kw.name))


class KeywordTypeEqual(KeywordEqual):
"""Match keyword based on the type."""

def __init__(self, expected_value: Optional[str]) -> None:
"""Initialize the matcher with the expected value."""
super().__init__(lambda kw: kw.keyword_type == expected_value)


class KeywordTagMatch(KeywordMatch):
"""Match keyword based on the tag pattern."""

pattern: Optional[re.Pattern]

def __init__(self, pattern: Optional[str]) -> None:
"""Initialize the matcher with the pattern."""
self.pattern = translate_glob_to_regex(pattern)

def match(self, kw: Keyword) -> bool:
"""Check if the keyword matches the criteria."""
return next((True for t in kw.tags if match_pattern(self.pattern, t)), False)


class KeywordStatusEqual(KeywordEqual):
"""Match keyword based on the status."""

def __init__(self, status: str) -> None:
"""Initialize the matcher with the status."""
super().__init__(lambda kw: kw.status == status)

0 comments on commit 7cc9747

Please sign in to comment.