11import contextlib
22import copy
3+ import io
34import unittest
45import os
56import shutil
@@ -110,7 +111,7 @@ def test_mixed_file_types(self):
110111 },
111112 "other_schema" : {".xml" : "other_schema.xml" },
112113 }
113- with contextlib .redirect_stdout (None ):
114+ with contextlib .redirect_stdout (io . StringIO () ):
114115 result = sort_base_schemas (filenames )
115116 self .assertEqual (dict (result ), expected )
116117
@@ -121,7 +122,7 @@ def test_tsv_in_correct_subfolder(self):
121122 os .path .normpath ("hedtsv/wrong_folder/wrong_name_Tag.tsv" ), # Should be ignored
122123 ]
123124 expected = {"test_schema" : {".tsv" : os .path .normpath ("hedtsv/test_schema" )}}
124- with contextlib .redirect_stdout (None ):
125+ with contextlib .redirect_stdout (io . StringIO () ):
125126 result = sort_base_schemas (filenames )
126127 self .assertEqual (dict (result ), expected )
127128
@@ -134,7 +135,7 @@ def test_tsv_in_correct_subfolder2(self):
134135 expected = {
135136 os .path .normpath ("prerelease/test_schema" ): {".tsv" : os .path .normpath ("prerelease/hedtsv/test_schema" )}
136137 }
137- with contextlib .redirect_stdout (None ):
138+ with contextlib .redirect_stdout (io . StringIO () ):
138139 result = sort_base_schemas (filenames )
139140 self .assertEqual (dict (result ), expected )
140141
@@ -144,14 +145,14 @@ def test_ignored_files(self):
144145 os .path .normpath ("not_hedtsv/test_schema/test_schema_Tag.tsv" ), # Should be ignored
145146 ]
146147 expected = {"test_schema" : {".mediawiki" : "test_schema.mediawiki" }}
147- with contextlib .redirect_stdout (None ):
148+ with contextlib .redirect_stdout (io . StringIO () ):
148149 result = sort_base_schemas (filenames )
149150 self .assertEqual (dict (result ), expected )
150151
151152 def test_empty_input (self ):
152153 filenames = []
153154 expected = {}
154- with contextlib .redirect_stdout (None ):
155+ with contextlib .redirect_stdout (io . StringIO () ):
155156 result = sort_base_schemas (filenames )
156157 self .assertEqual (dict (result ), expected )
157158
@@ -173,7 +174,7 @@ def test_case_insensitive_extensions(self):
173174 "case_test_schema" : {".mediawiki" : "case_test_schema.MEDIAWIKI" },
174175 "case_other_schema" : {".xml" : "case_other_schema.XML" },
175176 }
176- with contextlib .redirect_stdout (None ):
177+ with contextlib .redirect_stdout (io . StringIO () ):
177178 result = sort_base_schemas (filenames )
178179 self .assertEqual (dict (result ), expected )
179180 finally :
@@ -198,21 +199,21 @@ def test_error_no_error(self):
198199 schema = load_schema_version ("8.4.0" )
199200 schema .save_as_xml (os .path .join (self .base_path , self .basename + ".xml" ))
200201 schema .save_as_dataframes (os .path .join (self .base_path , "hedtsv" , self .basename ))
201- with contextlib .redirect_stdout (None ):
202+ with contextlib .redirect_stdout (io . StringIO () ):
202203 issues = validate_all_schema_formats (os .path .join (self .base_path , self .basename ))
203204 self .assertTrue (issues )
204205 self .assertEqual (issues [0 ], "Error loading schema: No such file or directory" )
205206 schema .save_as_mediawiki (os .path .join (self .base_path , self .basename + ".mediawiki" ))
206207 schema .save_as_json (os .path .join (self .base_path , self .basename + ".json" ))
207208
208- with contextlib .redirect_stdout (None ):
209+ with contextlib .redirect_stdout (io . StringIO () ):
209210 self .assertEqual (validate_all_schema_formats (os .path .join (self .base_path , self .basename )), [])
210211
211212 schema_incorrect = load_schema_version ("8.2.0" )
212213 schema_incorrect .save_as_dataframes (os .path .join (self .base_path , "hedtsv" , self .basename ))
213214
214215 # Validate and expect errors
215- with contextlib .redirect_stdout (None ):
216+ with contextlib .redirect_stdout (io . StringIO () ):
216217 issues = validate_all_schema_formats (os .path .join (self .base_path , self .basename ))
217218 self .assertTrue (issues )
218219 # self.assertIn("Error loading schema: No columns to parse from file", issues[0])
@@ -226,7 +227,7 @@ def tearDownClass(cls):
226227class TestValidateSchema (unittest .TestCase ):
227228 def test_load_invalid_extension (self ):
228229 # Verify capital letters fail validation
229- with contextlib .redirect_stdout (None ):
230+ with contextlib .redirect_stdout (io . StringIO () ):
230231 self .assertIn ("Only fully lowercase extensions " , validate_schema ("does_not_matter.MEDIAWIKI" )[0 ])
231232 self .assertIn ("Only fully lowercase extensions " , validate_schema ("does_not_matter.Mediawiki" )[0 ])
232233 self .assertIn ("Only fully lowercase extensions " , validate_schema ("does_not_matter.XML" )[0 ])
@@ -256,7 +257,7 @@ def test_uppercase_extension_policy_enforcement(self):
256257 self .assertEqual (schema_files ["policy_test" ][".xml" ], uppercase_file )
257258
258259 # Step 2: validate_all_schemas should use actual path and reject per policy
259- with contextlib .redirect_stdout (None ):
260+ with contextlib .redirect_stdout (io . StringIO () ):
260261 issues = validate_all_schemas (schema_files )
261262
262263 # Should get policy violation, not FileNotFoundError
@@ -284,25 +285,31 @@ def setUpClass(cls):
284285
285286 def test_clean_schema_check_warnings_false (self ):
286287 """A fully compliant schema produces no issues with check_warnings=False."""
287- with contextlib .redirect_stdout (None ):
288+ with contextlib .redirect_stdout (io . StringIO () ):
288289 issues = validate_schema_object (self .clean_schema , "test" , check_warnings = False )
289290 self .assertEqual (issues , [])
290291
291292 def test_clean_schema_check_warnings_true (self ):
292293 """A fully compliant schema produces no issues with check_warnings=True."""
293- with contextlib .redirect_stdout (None ):
294+ with contextlib .redirect_stdout (io . StringIO () ):
294295 issues = validate_schema_object (self .clean_schema , "test" , check_warnings = True )
295296 self .assertEqual (issues , [])
296297
297298 def test_warning_schema_check_warnings_true_reports_issues (self ):
298299 """A prerelease version generates a warning that is reported when check_warnings=True."""
299- with contextlib .redirect_stdout (None ):
300+ with contextlib .redirect_stdout (io . StringIO () ):
300301 issues = validate_schema_object (self .warning_schema , "test" , check_warnings = True )
302+ combined = "\n " .join (issues )
301303 self .assertTrue (issues , "Expected at least one issue for prerelease version warning" )
304+ self .assertIn (
305+ "SCHEMA_PRERELEASE_VERSION_USED" ,
306+ combined ,
307+ "Expected SCHEMA_PRERELEASE_VERSION_USED warning code in output for prerelease version" ,
308+ )
302309
303310 def test_warning_schema_check_warnings_false_suppresses_warnings (self ):
304311 """Warnings are suppressed and validation passes when check_warnings=False."""
305- with contextlib .redirect_stdout (None ):
312+ with contextlib .redirect_stdout (io . StringIO () ):
306313 issues = validate_schema_object (self .warning_schema , "test" , check_warnings = False )
307314 self .assertEqual (issues , [])
308315
@@ -314,7 +321,7 @@ def test_validate_schema_default_is_warnings_false(self):
314321 "schema_tests" ,
315322 "HED8.2.0.mediawiki" ,
316323 )
317- with contextlib .redirect_stdout (None ):
324+ with contextlib .redirect_stdout (io . StringIO () ):
318325 default_issues = validate_schema (schema_path )
319326 explicit_issues = validate_schema (schema_path , check_warnings = False )
320327 self .assertEqual (default_issues , explicit_issues )
0 commit comments