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()

```

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

{"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"}]}