Skip to content
convertMD.py 4.48 KiB
Newer Older
from re import compile, match, findall, MULTILINE
from difflib import SequenceMatcher


def get_string_difference(string1: str, string2: str) -> str:
    differ = SequenceMatcher(None, string1, string2)
    differences = differ.get_opcodes()
    diff_string = ""

    for tag, i1, i2, j1, j2 in differences:
        if tag == 'delete' or tag == 'replace':
            diff_string += string1[i1:i2]
        elif tag == 'insert' or tag == 'replace':
            diff_string += string2[j1:j2]

    return diff_string


class Markdown:
    def __init__(self, filename: str, previous_content: str):
        # Read the content of the input file
        with open(filename, 'r') as file:
            self.content = file.read()
        file.close()

        # Initial previous content
        if previous_content != '':
            # If there was a previous content in the file, take the difference to do the process
            self.content = get_string_difference(string1=previous_content, string2=self.content)

        self.data = {
            "suite": str(),
            "cases": list(),
            "steps": list()
        }

        self.markdown_content = str()

    def get_names(self):
        pattern1 = compile('^(\S+.*)$', MULTILINE)

        aux = findall(pattern=pattern1, string=self.content)

        special_lines = ['Response:', 'Request:', 'Mismatch:', f'{"=" * 150}', f'{"=" * 80}', f'{"-" * 80}']
        xs = [x for x in aux if x not in special_lines]

        prefixes_to_remove = ["Item ", "+ ", "- ", "Value of ", "HTTP status code", "HTTPError:", "AttributeError:"]
        xs = [item for item in xs if not any(item.startswith(prefix) for prefix in prefixes_to_remove)]

        # Get the name of the Test Suite
        self.data["suite"] = xs[0]

        # Get the names of the Test Cases
        try:
            pattern = r"\d{3}\w+"
            self.data["cases"] = [item for item in xs if match(pattern, item)]
        except IndexError as err:
            print(f'\n[ERROR] Unexpected {err=}, {type(err)=} in TC {self.suite_name}\n\n')

        # Get the rest of values -> Steps
        # Get items from listA not present in listB and not equal to exclude_string
        self.data['steps'] = [item for item in xs if item not in self.data['cases'] and item != self.data['suite']]
        self.data['steps'] = list(set(self.data['steps']))

    def generate_md(self):
        # Replace the title of the Test Suite
        self.markdown_content = self.content
        self.markdown_content = (
            self.markdown_content.replace(f'{"=" * 150}\n{self.data["suite"]}\n{"=" * 150}', f'# {self.data["suite"]}'))

        # Replace the name of the Test Cases
        for x in self.data['cases']:
            self.markdown_content = (
                self.markdown_content.replace(f'{x}\n{"=" * 80}\n', f'```\n## {x}\n'))

        # Replace Request, Response, and Mismatch
        self.markdown_content = (self.markdown_content.replace(f'Request:\n{"-" * 80}', '#### Request:\n```')
                                 .replace(f'Response:\n{"-" * 80}', '```\n\n#### Response:\n```')
                                 .replace(f'Mismatch:\n{"-" * 80}', '```\n\n#### Mismatch:\n```'))

        # Replace the name of the steps
        for x in self.data['steps']:
            self.markdown_content = (
                self.markdown_content.replace(f'{x}\n', f'```\n### {x}\n'))

        # Final steps, correct the code style for the title of the Test Cases
        # Define patterns and replacement strings
        index = True
        for x in self.data['cases']:
            if index:
                self.markdown_content = (
                    self.markdown_content.replace(f'```\n## {x}\n\n```\n', f'## {x}\n\n'))
                index = False
            else:
                self.markdown_content = (
                    self.markdown_content.replace(f'```\n## {x}\n\n```\n', f'```\n## {x}\n\n'))

        # If the final number of "```" is odd, means that we need to close the last code section
        # this is a workaround to close the last section of code if this is keep open
        count = self.markdown_content.count("```")
        if count % 2 == 1:
            print(True)
            self.markdown_content = f"{self.markdown_content}\n```"

    def save_file(self, filename: str):
        # Write the Markdown content to the output file
        with open(filename, 'a') as file:
            file.write(self.markdown_content)
        file.close()

        return self.content

    def get_markdown(self) -> str:
        return self.markdown_content