prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Complete folder structure for test suite
  Each file should have a docstring explaining it's intended purpose.
  Add a code coverage tool
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `csunplugged/utils/BaseLoader.py`
  Content:
  ```
  1 """Base loader used to create custom loaders for content."""
  2 
  3 import yaml
  4 import mdx_math
  5 import abc
  6 import sys
  7 import re
  8 import os.path
  9 from os import listdir
  10 from verto import Verto
  11 
  12 from .check_required_files import check_converter_required_files
  13 
  14 from utils.errors.CouldNotFindMarkdownFileError import CouldNotFindMarkdownFileError
  15 from utils.errors.EmptyMarkdownFileError import EmptyMarkdownFileError
  16 from utils.errors.EmptyConfigFileError import EmptyConfigFileError
  17 from utils.errors.InvalidConfigFileError import InvalidConfigFileError
  18 from utils.errors.NoHeadingFoundInMarkdownFileError import NoHeadingFoundInMarkdownFileError
  19 from utils.errors.CouldNotFindConfigFileError import CouldNotFindConfigFileError
  20 
  21 
  22 class BaseLoader():
  23     """Base loader class for individual loaders."""
  24 
  25     def __init__(self, BASE_PATH="", load_log=[]):
  26         """Create a BaseLoader object.
  27 
  28         Args:
  29             BASE_PATH: string of base path.
  30             load_log: list of log messages.
  31         """
  32         if load_log:
  33             self.load_log = load_log
  34         else:
  35             self.load_log = list(load_log)
  36         self.BASE_PATH = BASE_PATH
  37         self.setup_md_to_html_converter()
  38 
  39     def setup_md_to_html_converter(self):
  40         """Create Markdown converter.
  41 
  42         The converter is created with custom processors, html templates,
  43         and extensions.
  44         """
  45         templates = self.load_template_files()
  46         extensions = [
  47             "markdown.extensions.fenced_code",
  48             "markdown.extensions.codehilite",
  49             "markdown.extensions.sane_lists",
  50             "markdown.extensions.tables",
  51             mdx_math.MathExtension(enable_dollar_delimiter=True)
  52         ]
  53         self.converter = Verto(html_templates=templates, extensions=extensions)
  54         custom_processors = self.converter.processor_defaults()
  55         custom_processors.add("remove-title")
  56         self.converter.update_processors(custom_processors)
  57 
  58     def convert_md_file(self, md_file_path, config_file_path, heading_required=True):
  59         """Return the Verto object for a given Markdown file.
  60 
  61         Args:
  62             md_file_path: location of Markdown file to convert
  63 
  64         Returns:
  65             VertoResult object
  66 
  67         Raises:
  68             CouldNotFindMarkdownFileError: when a given Markdown file cannot be found.
  69             NoHeadingFoundInMarkdownFileError: when no heading can be found in a given
  70                 Markdown file.
  71             EmptyMarkdownFileError: when no content can be found in a given Markdown
  72                 file.
  73         """
  74         try:
  75             # check file exists
  76             content = open(md_file_path, encoding="UTF-8").read()
  77         except:
  78             raise CouldNotFindMarkdownFileError(md_file_path, config_file_path)
  79 
  80         result = self.converter.convert(content)
  81 
  82         if heading_required:
  83             if result.title is None:
  84                 raise NoHeadingFoundInMarkdownFileError(md_file_path)
  85 
  86         if len(result.html_string) == 0:
  87             raise EmptyMarkdownFileError(md_file_path)
  88 
  89         check_converter_required_files(result.required_files, md_file_path)
  90         return result
  91 
  92     def log(self, log_message, indent_amount=0):
  93         """Add the log message to the load log with the specified indent."""
  94         self.load_log.append((log_message, indent_amount))
  95 
  96     def print_load_log(self):
  97         """Output log messages from loader to console."""
  98         for (log, indent_amount) in self.load_log:
  99             indent = "  " * indent_amount
  100             sys.stdout.write("{indent}{text}\n".format(indent=indent, text=log))
  101         sys.stdout.write("\n")
  102         self.load_log = []
  103 
  104     def load_yaml_file(self, yaml_file_path):
  105         """Load and read given YAML file.
  106 
  107         Args:
  108             file_path: location of yaml file to read
  109 
  110         Returns:
  111             Either list or string, depending on structure of given yaml file
  112 
  113         Raises:
  114             CouldNotFindConfigFileError: when a given config file cannot be found.
  115             InvalidConfigFileError: when a given config file is incorrectly formatted.
  116             EmptyConfigFileError: when a give config file is empty.
  117         """
  118         try:
  119             yaml_file = open(yaml_file_path, encoding="UTF-8").read()
  120         except:
  121             raise CouldNotFindConfigFileError(yaml_file_path)
  122 
  123         try:
  124             yaml_contents = yaml.load(yaml_file)
  125         except:
  126             raise InvalidConfigFileError(yaml_file_path)
  127 
  128         if yaml_contents is None:
  129             raise EmptyConfigFileError(yaml_file_path)
  130 
  131         if isinstance(yaml_contents, dict) is False:
  132             raise InvalidConfigFileError(yaml_file_path)
  133 
  134         return yaml_contents
  135 
  136     def load_template_files(self):
  137         """Load custom HTML templates for converter.
  138 
  139         Returns:
  140             templates: dictionary of html templates
  141         """
  142         templates = dict()
  143         template_path = os.path.join(
  144             os.path.dirname(__file__),
  145             "custom_converter_templates/"
  146         )
  147         for file in listdir(template_path):
  148             template_file = re.search(r"(.*?).html$", file)
  149             if template_file:
  150                 template_name = template_file.groups()[0]
  151                 templates[template_name] = open(template_path + file).read()
  152         return templates
  153 
  154     @abc.abstractmethod
  155     def load(self):
  156         """Abstract method to be implemented by subclasses.
  157 
  158         Raise:
  159             NotImplementedError: when a user attempts to run the load() method of the
  160                 BaseLoader class.
  161         """
  162         raise NotImplementedError("Subclass does not implement this method")
  163
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/csunplugged/utils/BaseLoader.py b/csunplugged/utils/BaseLoader.py
  --- a/csunplugged/utils/BaseLoader.py
  +++ b/csunplugged/utils/BaseLoader.py
  @@ -10,7 +10,6 @@
   from verto import Verto
   
   from .check_required_files import check_converter_required_files
  -
   from utils.errors.CouldNotFindMarkdownFileError import CouldNotFindMarkdownFileError
   from utils.errors.EmptyMarkdownFileError import EmptyMarkdownFileError
   from utils.errors.EmptyConfigFileError import EmptyConfigFileError
  
verification_info: {"golden_diff": "diff --git a/csunplugged/utils/BaseLoader.py b/csunplugged/utils/BaseLoader.py\n--- a/csunplugged/utils/BaseLoader.py\n+++ b/csunplugged/utils/BaseLoader.py\n@@ -10,7 +10,6 @@\n from verto import Verto\n \n from .check_required_files import check_converter_required_files\n-\n from utils.errors.CouldNotFindMarkdownFileError import CouldNotFindMarkdownFileError\n from utils.errors.EmptyMarkdownFileError import EmptyMarkdownFileError\n from utils.errors.EmptyConfigFileError import EmptyConfigFileError\n", "issue": "Complete folder structure for test suite\nEach file should have a docstring explaining it's intended purpose.\nAdd a code coverage tool\n\n", "before_files": [{"content": "\"\"\"Base loader used to create custom loaders for content.\"\"\"\n\nimport yaml\nimport mdx_math\nimport abc\nimport sys\nimport re\nimport os.path\nfrom os import listdir\nfrom verto import Verto\n\nfrom .check_required_files import check_converter_required_files\n\nfrom utils.errors.CouldNotFindMarkdownFileError import CouldNotFindMarkdownFileError\nfrom utils.errors.EmptyMarkdownFileError import EmptyMarkdownFileError\nfrom utils.errors.EmptyConfigFileError import EmptyConfigFileError\nfrom utils.errors.InvalidConfigFileError import InvalidConfigFileError\nfrom utils.errors.NoHeadingFoundInMarkdownFileError import NoHeadingFoundInMarkdownFileError\nfrom utils.errors.CouldNotFindConfigFileError import CouldNotFindConfigFileError\n\n\nclass BaseLoader():\n    \"\"\"Base loader class for individual loaders.\"\"\"\n\n    def __init__(self, BASE_PATH=\"\", load_log=[]):\n        \"\"\"Create a BaseLoader object.\n\n        Args:\n            BASE_PATH: string of base path.\n            load_log: list of log messages.\n        \"\"\"\n        if load_log:\n            self.load_log = load_log\n        else:\n            self.load_log = list(load_log)\n        self.BASE_PATH = BASE_PATH\n        self.setup_md_to_html_converter()\n\n    def setup_md_to_html_converter(self):\n        \"\"\"Create Markdown converter.\n\n        The converter is created with custom processors, html templates,\n        and extensions.\n        \"\"\"\n        templates = self.load_template_files()\n        extensions = [\n            \"markdown.extensions.fenced_code\",\n            \"markdown.extensions.codehilite\",\n            \"markdown.extensions.sane_lists\",\n            \"markdown.extensions.tables\",\n            mdx_math.MathExtension(enable_dollar_delimiter=True)\n        ]\n        self.converter = Verto(html_templates=templates, extensions=extensions)\n        custom_processors = self.converter.processor_defaults()\n        custom_processors.add(\"remove-title\")\n        self.converter.update_processors(custom_processors)\n\n    def convert_md_file(self, md_file_path, config_file_path, heading_required=True):\n        \"\"\"Return the Verto object for a given Markdown file.\n\n        Args:\n            md_file_path: location of Markdown file to convert\n\n        Returns:\n            VertoResult object\n\n        Raises:\n            CouldNotFindMarkdownFileError: when a given Markdown file cannot be found.\n            NoHeadingFoundInMarkdownFileError: when no heading can be found in a given\n                Markdown file.\n            EmptyMarkdownFileError: when no content can be found in a given Markdown\n                file.\n        \"\"\"\n        try:\n            # check file exists\n            content = open(md_file_path, encoding=\"UTF-8\").read()\n        except:\n            raise CouldNotFindMarkdownFileError(md_file_path, config_file_path)\n\n        result = self.converter.convert(content)\n\n        if heading_required:\n            if result.title is None:\n                raise NoHeadingFoundInMarkdownFileError(md_file_path)\n\n        if len(result.html_string) == 0:\n            raise EmptyMarkdownFileError(md_file_path)\n\n        check_converter_required_files(result.required_files, md_file_path)\n        return result\n\n    def log(self, log_message, indent_amount=0):\n        \"\"\"Add the log message to the load log with the specified indent.\"\"\"\n        self.load_log.append((log_message, indent_amount))\n\n    def print_load_log(self):\n        \"\"\"Output log messages from loader to console.\"\"\"\n        for (log, indent_amount) in self.load_log:\n            indent = \"  \" * indent_amount\n            sys.stdout.write(\"{indent}{text}\\n\".format(indent=indent, text=log))\n        sys.stdout.write(\"\\n\")\n        self.load_log = []\n\n    def load_yaml_file(self, yaml_file_path):\n        \"\"\"Load and read given YAML file.\n\n        Args:\n            file_path: location of yaml file to read\n\n        Returns:\n            Either list or string, depending on structure of given yaml file\n\n        Raises:\n            CouldNotFindConfigFileError: when a given config file cannot be found.\n            InvalidConfigFileError: when a given config file is incorrectly formatted.\n            EmptyConfigFileError: when a give config file is empty.\n        \"\"\"\n        try:\n            yaml_file = open(yaml_file_path, encoding=\"UTF-8\").read()\n        except:\n            raise CouldNotFindConfigFileError(yaml_file_path)\n\n        try:\n            yaml_contents = yaml.load(yaml_file)\n        except:\n            raise InvalidConfigFileError(yaml_file_path)\n\n        if yaml_contents is None:\n            raise EmptyConfigFileError(yaml_file_path)\n\n        if isinstance(yaml_contents, dict) is False:\n            raise InvalidConfigFileError(yaml_file_path)\n\n        return yaml_contents\n\n    def load_template_files(self):\n        \"\"\"Load custom HTML templates for converter.\n\n        Returns:\n            templates: dictionary of html templates\n        \"\"\"\n        templates = dict()\n        template_path = os.path.join(\n            os.path.dirname(__file__),\n            \"custom_converter_templates/\"\n        )\n        for file in listdir(template_path):\n            template_file = re.search(r\"(.*?).html$\", file)\n            if template_file:\n                template_name = template_file.groups()[0]\n                templates[template_name] = open(template_path + file).read()\n        return templates\n\n    @abc.abstractmethod\n    def load(self):\n        \"\"\"Abstract method to be implemented by subclasses.\n\n        Raise:\n            NotImplementedError: when a user attempts to run the load() method of the\n                BaseLoader class.\n        \"\"\"\n        raise NotImplementedError(\"Subclass does not implement this method\")\n", "path": "csunplugged/utils/BaseLoader.py"}], "after_files": [{"content": "\"\"\"Base loader used to create custom loaders for content.\"\"\"\n\nimport yaml\nimport mdx_math\nimport abc\nimport sys\nimport re\nimport os.path\nfrom os import listdir\nfrom verto import Verto\n\nfrom .check_required_files import check_converter_required_files\nfrom utils.errors.CouldNotFindMarkdownFileError import CouldNotFindMarkdownFileError\nfrom utils.errors.EmptyMarkdownFileError import EmptyMarkdownFileError\nfrom utils.errors.EmptyConfigFileError import EmptyConfigFileError\nfrom utils.errors.InvalidConfigFileError import InvalidConfigFileError\nfrom utils.errors.NoHeadingFoundInMarkdownFileError import NoHeadingFoundInMarkdownFileError\nfrom utils.errors.CouldNotFindConfigFileError import CouldNotFindConfigFileError\n\n\nclass BaseLoader():\n    \"\"\"Base loader class for individual loaders.\"\"\"\n\n    def __init__(self, BASE_PATH=\"\", load_log=[]):\n        \"\"\"Create a BaseLoader object.\n\n        Args:\n            BASE_PATH: string of base path.\n            load_log: list of log messages.\n        \"\"\"\n        if load_log:\n            self.load_log = load_log\n        else:\n            self.load_log = list(load_log)\n        self.BASE_PATH = BASE_PATH\n        self.setup_md_to_html_converter()\n\n    def setup_md_to_html_converter(self):\n        \"\"\"Create Markdown converter.\n\n        The converter is created with custom processors, html templates,\n        and extensions.\n        \"\"\"\n        templates = self.load_template_files()\n        extensions = [\n            \"markdown.extensions.fenced_code\",\n            \"markdown.extensions.codehilite\",\n            \"markdown.extensions.sane_lists\",\n            \"markdown.extensions.tables\",\n            mdx_math.MathExtension(enable_dollar_delimiter=True)\n        ]\n        self.converter = Verto(html_templates=templates, extensions=extensions)\n        custom_processors = self.converter.processor_defaults()\n        custom_processors.add(\"remove-title\")\n        self.converter.update_processors(custom_processors)\n\n    def convert_md_file(self, md_file_path, config_file_path, heading_required=True):\n        \"\"\"Return the Verto object for a given Markdown file.\n\n        Args:\n            md_file_path: location of Markdown file to convert\n\n        Returns:\n            VertoResult object\n\n        Raises:\n            CouldNotFindMarkdownFileError: when a given Markdown file cannot be found.\n            NoHeadingFoundInMarkdownFileError: when no heading can be found in a given\n                Markdown file.\n            EmptyMarkdownFileError: when no content can be found in a given Markdown\n                file.\n        \"\"\"\n        try:\n            # check file exists\n            content = open(md_file_path, encoding=\"UTF-8\").read()\n        except:\n            raise CouldNotFindMarkdownFileError(md_file_path, config_file_path)\n\n        result = self.converter.convert(content)\n\n        if heading_required:\n            if result.title is None:\n                raise NoHeadingFoundInMarkdownFileError(md_file_path)\n\n        if len(result.html_string) == 0:\n            raise EmptyMarkdownFileError(md_file_path)\n\n        check_converter_required_files(result.required_files, md_file_path)\n        return result\n\n    def log(self, log_message, indent_amount=0):\n        \"\"\"Add the log message to the load log with the specified indent.\"\"\"\n        self.load_log.append((log_message, indent_amount))\n\n    def print_load_log(self):\n        \"\"\"Output log messages from loader to console.\"\"\"\n        for (log, indent_amount) in self.load_log:\n            indent = \"  \" * indent_amount\n            sys.stdout.write(\"{indent}{text}\\n\".format(indent=indent, text=log))\n        sys.stdout.write(\"\\n\")\n        self.load_log = []\n\n    def load_yaml_file(self, yaml_file_path):\n        \"\"\"Load and read given YAML file.\n\n        Args:\n            file_path: location of yaml file to read\n\n        Returns:\n            Either list or string, depending on structure of given yaml file\n\n        Raises:\n            CouldNotFindConfigFileError: when a given config file cannot be found.\n            InvalidConfigFileError: when a given config file is incorrectly formatted.\n            EmptyConfigFileError: when a give config file is empty.\n        \"\"\"\n        try:\n            yaml_file = open(yaml_file_path, encoding=\"UTF-8\").read()\n        except:\n            raise CouldNotFindConfigFileError(yaml_file_path)\n\n        try:\n            yaml_contents = yaml.load(yaml_file)\n        except:\n            raise InvalidConfigFileError(yaml_file_path)\n\n        if yaml_contents is None:\n            raise EmptyConfigFileError(yaml_file_path)\n\n        if isinstance(yaml_contents, dict) is False:\n            raise InvalidConfigFileError(yaml_file_path)\n\n        return yaml_contents\n\n    def load_template_files(self):\n        \"\"\"Load custom HTML templates for converter.\n\n        Returns:\n            templates: dictionary of html templates\n        \"\"\"\n        templates = dict()\n        template_path = os.path.join(\n            os.path.dirname(__file__),\n            \"custom_converter_templates/\"\n        )\n        for file in listdir(template_path):\n            template_file = re.search(r\"(.*?).html$\", file)\n            if template_file:\n                template_name = template_file.groups()[0]\n                templates[template_name] = open(template_path + file).read()\n        return templates\n\n    @abc.abstractmethod\n    def load(self):\n        \"\"\"Abstract method to be implemented by subclasses.\n\n        Raise:\n            NotImplementedError: when a user attempts to run the load() method of the\n                BaseLoader class.\n        \"\"\"\n        raise NotImplementedError(\"Subclass does not implement this method\")\n", "path": "csunplugged/utils/BaseLoader.py"}]}