Skip to content

Commit

Permalink
Merge pull request #191 from chrisdavi/python_38_support
Browse files Browse the repository at this point in the history
Added python 3.8 support
  • Loading branch information
bitcoder authored Dec 20, 2023
2 parents e82423f + 09b5bbd commit 0ec72d9
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 37 deletions.
3 changes: 2 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import trcli.cli
from shutil import copyfile
from trcli.cli import cli
from trcli.backports import removeprefix
from trcli.constants import FAULT_MAPPING
from tests.helpers.cli_helpers import CLIParametersHelper

Expand Down Expand Up @@ -241,7 +242,7 @@ def test_default_config_does_not_override_environments(self, mocker, cli_resourc

for arg_name, arg_value in ENVIRONMENT_VARIABLES.items():
setattr_mock.assert_any_call(
mocker.ANY, arg_name.removeprefix("TR_CLI_").lower(), arg_value
mocker.ANY, removeprefix(arg_name, "TR_CLI_").lower(), arg_value
)

@pytest.mark.cli
Expand Down
4 changes: 2 additions & 2 deletions trcli/api/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pathlib import Path

import requests
from typing import Union, Callable
from typing import Union, Callable, Dict, List
from time import sleep

import urllib3
Expand All @@ -22,7 +22,7 @@ class APIClientResult:
error_message - custom error message when -1 was returned in status_code"""

status_code: int
response_text: Union[dict, str, list]
response_text: Union[Dict, str, List]
error_message: str


Expand Down
20 changes: 10 additions & 10 deletions trcli/api/api_request_handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import html
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List, Union, Tuple
from typing import List, Union, Tuple, Dict

from trcli.api.api_client import APIClient, APIClientResult
from trcli.api.api_response_verify import ApiResponseVerify
Expand Down Expand Up @@ -46,7 +46,7 @@ def check_automation_id_field(self, project_id: int) -> Union[str, None]:
"""
response = self.client.send_get("get_case_fields")
if not response.error_message:
fields: list = response.response_text
fields: List = response.response_text
automation_id_field = next(
filter(lambda x: x["system_name"] == "custom_automation_id", fields),
None
Expand Down Expand Up @@ -181,7 +181,7 @@ def get_suite_ids(self, project_id: int) -> Tuple[List[int], str]:
) > 0 else "Update skipped"
return available_suites, error_message

def add_suites(self, project_id: int) -> Tuple[List[dict], str]:
def add_suites(self, project_id: int) -> Tuple[List[Dict], str]:
"""
Adds suites that doesn't have ID's in DataProvider.
Runs update_data in data_provider for successfully created resources.
Expand Down Expand Up @@ -244,7 +244,7 @@ def check_missing_section_ids(self, project_id: int) -> Tuple[bool, str]:
else:
return False, error_message

def add_sections(self, project_id: int) -> Tuple[List[dict], str]:
def add_sections(self, project_id: int) -> Tuple[List[Dict], str]:
"""
Add sections that doesn't have ID in DataProvider.
Runs update_data in data_provider for successfully created resources.
Expand Down Expand Up @@ -373,7 +373,7 @@ def add_run(
run_name: str,
milestone_id: int = None,
plan_id: int = None,
config_ids: list[int] = None
config_ids: List[int] = None
) -> Tuple[int, str]:
"""
Creates a new test run.
Expand Down Expand Up @@ -435,7 +435,7 @@ def update_run(self, run_id: int, run_name: str, milestone_id: int = None) -> Tu
run_response = self.client.send_get(f"get_run/{run_id}")
return run_response.response_text, update_response.error_message

def upload_attachments(self, report_results: [dict], results: list[dict], run_id: int):
def upload_attachments(self, report_results: [Dict], results: List[Dict], run_id: int):
""" Getting test result id and upload attachments for it. """
tests_in_run, error = self.__get_all_tests_in_run(run_id)
if not error:
Expand All @@ -452,7 +452,7 @@ def upload_attachments(self, report_results: [dict], results: list[dict], run_id
else:
self.environment.elog(f"Unable to upload attachments due to API request error: {error}")

def add_results(self, run_id: int) -> Tuple[list, str, int]:
def add_results(self, run_id: int) -> Tuple[List, str, int]:
"""
Adds one or more new test results.
:run_id: run id
Expand Down Expand Up @@ -564,7 +564,7 @@ def delete_suite(self, suite_id: int) -> Tuple[dict, str]:
response = self.client.send_post(f"delete_suite/{suite_id}", payload={})
return response.response_text, response.error_message

def delete_sections(self, added_sections: List[dict]) -> Tuple[list, str]:
def delete_sections(self, added_sections: List[Dict]) -> Tuple[List, str]:
"""
Delete section given add_sections response
:suite_id: section id
Expand All @@ -583,7 +583,7 @@ def delete_sections(self, added_sections: List[dict]) -> Tuple[list, str]:
break
return responses, error_message

def delete_cases(self, suite_id: int, added_cases: List[dict]) -> Tuple[dict, str]:
def delete_cases(self, suite_id: int, added_cases: List[Dict]) -> Tuple[Dict, str]:
"""
Delete cases given add_cases response
:suite_id: section id
Expand Down Expand Up @@ -654,7 +654,7 @@ def __get_all_projects(self) -> Tuple[List[dict], str]:
"""
return self.__get_all_entities('projects', f"get_projects")

def __get_all_entities(self, entity: str, link=None, entities=[]) -> Tuple[List[dict], str]:
def __get_all_entities(self, entity: str, link=None, entities=[]) -> Tuple[List[Dict], str]:
"""
Get all entities from all pages if number of entities is too big to return in single response.
Function using next page field in API response.
Expand Down
2 changes: 1 addition & 1 deletion trcli/api/results_uploader.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def check_suite_id(self, project_id: int) -> int:
self.environment.elog(error_message)
return result_code

def add_missing_sections(self, project_id: int) -> Tuple[list, int]:
def add_missing_sections(self, project_id: int) -> Tuple[List, int]:
"""
Checks for missing sections in specified project. Add missing sections if user agrees to
do so. Returns list of added section IDs if succeeds or empty list with result_code set to
Expand Down
6 changes: 6 additions & 0 deletions trcli/backports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def removeprefix(text, prefix):
"""Backport of python 3.9 str.removeprefix"""

if text.startswith(prefix):
return text[len(prefix):]
return text
4 changes: 2 additions & 2 deletions trcli/data_classes/data_parsers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import re
from typing import Union
from typing import Union, List, Dict


class MatchersParser:
Expand Down Expand Up @@ -49,7 +49,7 @@ def parse_name_with_id(case_name: str) -> (int, str):
class FieldsParser:

@staticmethod
def resolve_fields(fields: Union[list[str], dict]) -> (dict, str):
def resolve_fields(fields: Union[List[str], Dict]) -> (Dict, str):
error = None
fields_dictionary = {}
try:
Expand Down
10 changes: 5 additions & 5 deletions trcli/data_classes/dataclass_testrail.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class TestRailResult:
assignedto_id: int = field(default=None, skip_if_default=True)
attachments: Optional[List[str]] = field(default_factory=list, skip_if_default=True)
result_fields: Optional[dict] = field(default_factory=dict, skip=True)
junit_result_unparsed: list = field(default=None, metadata={"serde_skip": True})
custom_step_results: list[TestRailSeparatedStep] = field(default_factory=list, skip_if_default=True)
junit_result_unparsed: List = field(default=None, metadata={"serde_skip": True})
custom_step_results: List[TestRailSeparatedStep] = field(default_factory=list, skip_if_default=True)

def __post_init__(self):
if self.junit_result_unparsed is not None:
Expand All @@ -51,7 +51,7 @@ def __post_init__(self):
self.elapsed = self.proper_format_for_elapsed(self.elapsed)

@staticmethod
def calculate_status_id_from_junit_element(junit_result: list) -> int:
def calculate_status_id_from_junit_element(junit_result: List) -> int:
"""
Calculate id for first result. In junit no result mean pass
1 - Passed
Expand All @@ -68,7 +68,7 @@ def calculate_status_id_from_junit_element(junit_result: list) -> int:
return 5

@staticmethod
def get_comment_from_junit_element(junit_result: list) -> str:
def get_comment_from_junit_element(junit_result: List) -> str:
if len(junit_result) == 0:
return ""
elif not any(
Expand Down Expand Up @@ -136,7 +136,7 @@ class TestRailCase:
result: TestRailResult = field(default=None, metadata={"serde_skip": True})
custom_automation_id: str = field(default=None, skip_if_default=True)
# Uncomment if we want to support separated steps in cases in the future
# custom_steps_separated: list[TestRailSeparatedStep] = field(default_factory=list, skip_if_default=True)
# custom_steps_separated: List[TestRailSeparatedStep] = field(default_factory=list, skip_if_default=True)

def __int__(self):
return int(self.case_id) if self.case_id is not None else -1
Expand Down
14 changes: 7 additions & 7 deletions trcli/data_providers/api_data_provider.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import List, Dict

from serde.json import to_dict

Expand Down Expand Up @@ -109,9 +109,9 @@ def add_results_for_cases(self, bulk_size):

def update_data(
self,
suite_data: List[dict] = None,
section_data: List[dict] = None,
case_data: List[dict] = None,
suite_data: List[Dict] = None,
section_data: List[Dict] = None,
case_data: List[Dict] = None,
):
"""Here you can provide responses from service after creating resources.
This way TestRailSuite data will be updated by ID's of new created resources.
Expand All @@ -123,7 +123,7 @@ def update_data(
if case_data is not None:
self.__update_case_data(case_data)

def __update_suite_data(self, suite_data: List[dict]):
def __update_suite_data(self, suite_data: List[Dict]):
"""suite_data comes from add_suite API response
example:
{
Expand All @@ -146,7 +146,7 @@ def check_section_names_duplicates(self):
else:
return True

def __update_section_data(self, section_data: List[dict]):
def __update_section_data(self, section_data: List[Dict]):
"""section_data comes from add_section API response
example:
{
Expand All @@ -173,7 +173,7 @@ def __update_parent_section(self, parent_section_id: int):
for section in self.suites_input.testsections:
section.parent_id = parent_section_id

def __update_case_data(self, case_data: List[dict]):
def __update_case_data(self, case_data: List[Dict]):
"""case_data comes from add_case API response
example:
{
Expand Down
4 changes: 2 additions & 2 deletions trcli/readers/file_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pathlib import Path
from abc import abstractmethod
from typing import Union
from typing import Union, List

from trcli.cli import Environment
from trcli.data_classes.dataclass_testrail import TestRailSuite
Expand All @@ -24,5 +24,5 @@ def check_file(filepath: Union[str, Path]) -> Path:
return filepath

@abstractmethod
def parse_file(self) -> list[TestRailSuite]:
def parse_file(self) -> List[TestRailSuite]:
raise NotImplementedError
6 changes: 3 additions & 3 deletions trcli/readers/junit_xml.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import glob
from pathlib import Path
from typing import Union
from typing import Union, List
from unittest import TestCase, TestSuite
from xml.etree import ElementTree as etree

Expand Down Expand Up @@ -75,7 +75,7 @@ def check_file(filepath: Union[str, Path]) -> Path:
suite.write(merged_report_path)
return merged_report_path

def parse_file(self) -> list[TestRailSuite]:
def parse_file(self) -> List[TestRailSuite]:
self.env.log(f"Parsing JUnit report.")
suite = JUnitXml.fromfile(
self.filepath, parse_func=self._add_root_element_to_tree
Expand Down Expand Up @@ -188,7 +188,7 @@ def parse_file(self) -> list[TestRailSuite]:

return testrail_suites

def split_sauce_report(self, suite) -> list[JUnitXml]:
def split_sauce_report(self, suite) -> List[JUnitXml]:
self.env.log(f"Processing SauceLabs report.")
subsuites = {}
for section in suite:
Expand Down
3 changes: 2 additions & 1 deletion trcli/readers/openapi_yml.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
from pathlib import Path
from typing import List

import yaml

Expand Down Expand Up @@ -133,7 +134,7 @@ def _format_text(title, details):

class OpenApiParser(FileParser):

def parse_file(self) -> list[TestRailSuite]:
def parse_file(self) -> List[TestRailSuite]:
self.env.log(f"Parsing OpenAPI specification.")
spec = self.resolve_openapi_spec()
sections = {
Expand Down
8 changes: 5 additions & 3 deletions trcli/readers/robot_xml.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import datetime
from typing import List
from xml.etree import ElementTree

from trcli.backports import removeprefix
from trcli.cli import Environment
from trcli.data_classes.data_parsers import MatchersParser, FieldsParser
from trcli.data_classes.dataclass_testrail import (
Expand All @@ -18,7 +20,7 @@ def __init__(self, environment: Environment):
super().__init__(environment)
self.case_matcher = environment.case_matcher

def parse_file(self) -> list[TestRailSuite]:
def parse_file(self) -> List[TestRailSuite]:
self.env.log(f"Parsing Robot Framework report.")
tree = ElementTree.parse(self.filepath)
root = tree.getroot()
Expand All @@ -38,7 +40,7 @@ def parse_file(self) -> list[TestRailSuite]:

return testrail_suites

def _find_suites(self, suite_element, sections_list: list, namespace=""):
def _find_suites(self, suite_element, sections_list: List, namespace=""):
name = suite_element.get("name")
namespace += f".{name}" if namespace else name
tests = suite_element.findall("test")
Expand Down Expand Up @@ -124,4 +126,4 @@ def _parse_rf_time(time_str: str) -> datetime:

@staticmethod
def _remove_tr_prefix(text: str, tr_prefix: str) -> str:
return text.strip().removeprefix(tr_prefix).strip()
return removeprefix(text, tr_prefix).strip()

0 comments on commit 0ec72d9

Please sign in to comment.