33"""
44import os
55import re
6+ import typing as t
7+ from collections .abc import Callable , Sequence
68
79from click .testing import CliRunner
10+ from click .testing import Result as ClickTestResult
11+ from stevedore import named
812
9- from code_annotations .base import BaseSearch , VerboseEcho
13+ from code_annotations .base import AnnotationConfig , BaseSearch
1014from code_annotations .cli import entry_point
15+ from code_annotations .helpers import VerboseEcho
16+
17+ # Re-export Result for convenience
18+ Result = ClickTestResult
1119
1220EXIT_CODE_SUCCESS = 0
1321EXIT_CODE_FAILURE = 1
3442""" .format (DEFAULT_FAKE_SAFELIST_PATH )
3543
3644
37- class FakeConfig :
45+ class FakeConfig ( AnnotationConfig ) :
3846 """
3947 Simple config for testing without reading a config file.
4048 """
4149
42- annotations : dict [str , str ] = {}
43- annotation_regexes : list [str ] = []
44- annotation_tokens : list [str ] = []
45- groups : list [str ] = []
46- echo = VerboseEcho ()
50+ def __init__ (self ) -> None : # pylint: disable=super-init-not-called
51+ """
52+ Override the base __init__ to skip reading and parsing the config.
53+ """
54+ self .groups : dict [str , list [str ]] = {}
55+ self .choices : dict [str , list [str ]] = {}
56+ self .optional_groups : list [str ] = []
57+ self .annotation_tokens : list [str ] = []
58+ self .annotation_regexes : list [str ] = []
59+ self .mgr : named .NamedExtensionManager | None = None
60+ self .coverage_target : float | None = None
61+ self .echo = VerboseEcho ()
4762
4863
4964class FakeSearch (BaseSearch ):
5065 """
5166 Simple test class for directly testing BaseSearch since it's abstract.
5267 """
5368
54- def search (self ):
69+ def search (self ) -> dict [ str , list [ dict [ str , t . Any ]]] :
5570 """
5671 Override for abstract base method.
72+
73+ Returns:
74+ Empty dict to satisfy the abstract method requirement
5775 """
76+ return {}
5877
5978
60- def delete_report_files (file_extension ) :
79+ def delete_report_files (file_extension : str ) -> None :
6180 """
6281 Delete all files with the given extension from the test_reports directory.
6382
@@ -76,7 +95,7 @@ def delete_report_files(file_extension):
7695 pass
7796
7897
79- def call_script (args_list , delete_test_reports = True , delete_test_docs = True ):
98+ def call_script (args_list : Sequence [ str ] , delete_test_reports : bool = True , delete_test_docs : bool = True ) -> Result :
8099 """
81100 Call the code_annotations script with the given params and a generic config file.
82101
@@ -108,11 +127,11 @@ def call_script(args_list, delete_test_reports=True, delete_test_docs=True):
108127
109128
110129def call_script_isolated (
111- args_list ,
112- test_filesystem_cb = None ,
113- test_filesystem_report_cb = None ,
114- fake_safelist_data = "{}"
115- ):
130+ args_list : list [ str ] ,
131+ test_filesystem_cb : Callable [[], None ] | None = None ,
132+ test_filesystem_report_cb : Callable [[ str ], None ] | None = None ,
133+ fake_safelist_data : str = "{}"
134+ ) -> Result :
116135 """
117136 Call the code_annotations script with the given params and a generic config file.
118137
@@ -123,8 +142,6 @@ def call_script_isolated(
123142 test_filesystem_report_cb: Callback function, called after the command is run, before the temp filesystem
124143 is cleared. Callback is called with the raw text contents of the report file.
125144 fake_safelist_data: Raw text to write to the safelist file before the command is called.
126- safelist_path: File path to write the safelist to. Used when writing a fake safelist, but not automatically
127- passed to the command.
128145
129146 Returns:
130147 click.testing.Result: Result from the `CliRunner.invoke()` call.
@@ -151,7 +168,9 @@ def call_script_isolated(
151168
152169 if test_filesystem_report_cb :
153170 try :
154- report_file = re .search (r'Generating report to (.*)' , result .output ).groups ()[0 ]
171+ report_match = re .search (r'Generating report to (.*)' , result .output )
172+ assert report_match is not None
173+ report_file = report_match .groups ()[0 ]
155174 with open (report_file ) as f :
156175 report_contents = f .read ()
157176
@@ -163,7 +182,7 @@ def call_script_isolated(
163182 return result
164183
165184
166- def get_report_filename_from_output (output ) :
185+ def get_report_filename_from_output (output : str ) -> str | None :
167186 """
168187 Find the report filename in a find_static or find_django output and return it.
169188
@@ -172,9 +191,10 @@ def get_report_filename_from_output(output):
172191
173192 Returns:
174193 Filename of the found report, or None of no name is found
175-
176194 """
195+ match = re .search (r'Generating report to (.*)' , output )
196+ assert match is not None
177197 try :
178- return re . search ( r'Generating report to (.*)' , output ) .groups ()[0 ]
198+ return match .groups ()[0 ]
179199 except IndexError :
180200 return None
0 commit comments