Skip to content

Commit 6e34f3b

Browse files
committed
Addressed copilot review suggests and fixed skipped tests
1 parent 1bf29db commit 6e34f3b

6 files changed

Lines changed: 117 additions & 115 deletions

File tree

hed/errors/error_reporter.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,22 +286,23 @@ def filter_issues_by_severity(issues_list: list[dict], severity: int) -> list[di
286286
list[dict]: A list of dictionaries containing the issue list after filtering by severity.
287287
288288
"""
289-
return [issue for issue in issues_list if issue["severity"] <= severity]
289+
return [issue for issue in issues_list if issue.get("severity", ErrorSeverity.ERROR) <= severity]
290290

291291
@staticmethod
292292
def separate_issues(issues_list: list[dict]) -> tuple[list[dict], list[dict]]:
293293
"""Separate a list of issues into errors and warnings.
294294
295295
Parameters:
296-
issues_list (list[dict]): A list of issue dictionaries, each containing a 'severity' key.
296+
issues_list (list[dict]): A list of issue dictionaries. The 'severity' key is
297+
optional; issues that omit it are treated as errors (ErrorSeverity.ERROR).
297298
298299
Returns:
299300
tuple[list[dict], list[dict]]: A tuple of (errors, warnings) where errors contains
300301
issues with severity <= ErrorSeverity.ERROR and warnings contains issues with
301-
severity >= ErrorSeverity.WARNING.
302+
severity > ErrorSeverity.ERROR.
302303
"""
303-
errors = [issue for issue in issues_list if issue["severity"] <= ErrorSeverity.ERROR]
304-
warnings = [issue for issue in issues_list if issue["severity"] >= ErrorSeverity.WARNING]
304+
errors = [issue for issue in issues_list if issue.get("severity", ErrorSeverity.ERROR) <= ErrorSeverity.ERROR]
305+
warnings = [issue for issue in issues_list if issue.get("severity", ErrorSeverity.ERROR) > ErrorSeverity.ERROR]
305306
return errors, warnings
306307

307308
@staticmethod

hed/scripts/schema_script_util.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ def _is_prerelease_partner(base_schema) -> bool:
3232
return hed_cache.get_hed_version_path(with_standard, check_prerelease=False) is None
3333

3434

35-
def validate_schema_object(base_schema, schema_name, check_warnings=True):
36-
"""Validate a schema object by checking non-warning compliance and roundtrip conversion.
35+
def validate_schema_object(base_schema, schema_name, check_warnings=False):
36+
"""Validate a schema object by checking compliance and roundtrip conversion.
3737
38-
Tests the schema for non-warning compliance issues and validates that it can be successfully
38+
Tests the schema for compliance issues and validates that it can be successfully
3939
converted to and reloaded from all four formats (MEDIAWIKI, XML, JSON, TSV).
4040
4141
Parameters:
4242
base_schema (HedSchema): The schema object to validate.
4343
schema_name (str): The name/path of the schema for error reporting.
44-
check_warnings (bool): If True, include warnings in the validation. Default is True.
44+
check_warnings (bool): If True, include warnings in the validation. Default is False.
4545
4646
Returns:
4747
list: A list of validation issue strings. Empty if no issues found.
@@ -81,14 +81,14 @@ def validate_schema(file_path, check_warnings=False):
8181
8282
Loads the schema from file, checks the file extension is lowercase,
8383
and validates the schema object for compliance errors and roundtrip conversion.
84-
Does not check for warnings.
8584
8685
Parameters:
8786
file_path (str): The path to the schema file to validate.
8887
If loading a TSV file, this should be a single filename where:
8988
Template: basename.tsv, where files are named basename_Struct.tsv, basename_Tag.tsv, etc.
9089
Alternatively, you can point to a directory containing the .tsv files.
9190
check_warnings (bool): If True, include warnings in the validation. Default is False.
91+
9292
Returns:
9393
list: A list of validation issue strings. Empty if no issues found.
9494
"""

tests/errors/test_error_reporter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,10 @@ def test_original_list_unchanged(self):
339339
issues = [self._make_issue(ErrorSeverity.ERROR), self._make_issue(ErrorSeverity.WARNING)]
340340
ErrorHandler.separate_issues(issues)
341341
self.assertEqual(len(issues), 2)
342+
343+
def test_missing_severity_treated_as_error(self):
344+
"""Issues without a 'severity' key should be treated as errors, not raise KeyError."""
345+
issues = [{"message": "no severity"}, self._make_issue(ErrorSeverity.WARNING)]
346+
errors, warnings = ErrorHandler.separate_issues(issues)
347+
self.assertEqual(len(errors), 1, "Issue missing severity should default to ERROR")
348+
self.assertEqual(len(warnings), 1)

tests/scripts/test_hed_convert_schema.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import unittest
2-
import shutil
1+
import contextlib
32
import copy
3+
import io
44
import os
5+
import shutil
6+
import unittest
57
from hed import load_schema, load_schema_version
68
from hed.schema import HedSectionKey, HedKey
79
from hed.scripts.schema_script_util import add_extension
810
from hed.scripts.hed_convert_schema import convert_and_update
9-
import contextlib
1011

1112

1213
class TestConvertAndUpdate(unittest.TestCase):
@@ -25,7 +26,7 @@ def test_schema_conversion_and_update(self):
2526

2627
# Assume filenames updated includes just the original schema file for simplicity
2728
filenames = [original_name]
28-
with contextlib.redirect_stdout(None):
29+
with contextlib.redirect_stdout(io.StringIO()):
2930
result = convert_and_update(filenames, set_ids=False)
3031

3132
# Verify no error from convert_and_update and the correct schema version was saved
@@ -43,7 +44,7 @@ def test_schema_conversion_and_update(self):
4344
schema.save_as_dataframes(tsv_filename)
4445

4546
filenames = [os.path.join(tsv_filename, "test_schema_Tag.tsv")]
46-
with contextlib.redirect_stdout(None):
47+
with contextlib.redirect_stdout(io.StringIO()):
4748
result = convert_and_update(filenames, set_ids=False)
4849

4950
# Verify no error from convert_and_update and the correct schema version was saved
@@ -72,7 +73,7 @@ def test_schema_adding_tag(self):
7273

7374
# Assume filenames updated includes just the original schema file for simplicity
7475
filenames = [add_extension(basename, ".mediawiki")]
75-
with contextlib.redirect_stdout(None):
76+
with contextlib.redirect_stdout(io.StringIO()):
7677
result = convert_and_update(filenames, set_ids=False)
7778
self.assertEqual(result, 0)
7879

@@ -81,7 +82,7 @@ def test_schema_adding_tag(self):
8182
self.assertTrue(x)
8283
self.assertEqual(schema_reloaded, schema_edited)
8384

84-
with contextlib.redirect_stdout(None):
85+
with contextlib.redirect_stdout(io.StringIO()):
8586
result = convert_and_update(filenames, set_ids=True)
8687
self.assertEqual(result, 0)
8788

tests/scripts/test_script_util.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import contextlib
22
import copy
3+
import io
34
import unittest
45
import os
56
import 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):
226227
class 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

Comments
 (0)