From 7f3af48ee45494e214c98a95142130b8244fe46f Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 25 Jan 2024 17:49:22 +0100 Subject: [PATCH 1/2] tests refactor Signed-off-by: Jan Kowalleck --- tests/__init__.py | 7 ++++++- tests/test_deserialize_json.py | 8 +++++--- tests/test_deserialize_xml.py | 19 ++++++++++++++++--- tests/test_enums.py | 9 ++------- tests/test_output_json.py | 10 +++++----- tests/test_output_xml.py | 15 +++++++++++++-- tests/test_validation.py | 19 +++++++++---------- tests/test_validation_json.py | 12 ++++++------ tests/test_validation_xml.py | 10 +++++----- 9 files changed, 67 insertions(+), 42 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index b4d98ddc..8bcae6b3 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -17,7 +17,7 @@ from os import getenv, path from os.path import join -from typing import TYPE_CHECKING, Any, Generator, Iterable, List, Optional, TypeVar, Union +from typing import TYPE_CHECKING, Any, Dict, Generator, Iterable, List, Optional, Set, TypeVar, Union from unittest import TestCase from uuid import UUID @@ -37,6 +37,11 @@ OWN_DATA_DIRECTORY = path.join(_TESTDATA_DIRECTORY, 'own') SNAPSHOTS_DIRECTORY = path.join(_TESTDATA_DIRECTORY, 'snapshots') +UNDEFINED_SCHEMA_VERSIONS: Dict[OutputFormat, Set[SchemaVersion]] = { + OutputFormat.XML: set(), + OutputFormat.JSON: {SchemaVersion.V1_0, SchemaVersion.V1_1, }, +} + RECREATE_SNAPSHOTS = '1' == getenv('CDX_TEST_RECREATE_SNAPSHOTS') if RECREATE_SNAPSHOTS: print('!!! WILL RECREATE ALL SNAPSHOTS !!!') diff --git a/tests/test_deserialize_json.py b/tests/test_deserialize_json.py index 41ad1010..1f657ad7 100644 --- a/tests/test_deserialize_json.py +++ b/tests/test_deserialize_json.py @@ -27,9 +27,12 @@ from cyclonedx.model.bom import Bom from cyclonedx.model.license import DisjunctiveLicense, LicenseExpression, LicenseRepository from cyclonedx.schema import OutputFormat, SchemaVersion -from tests import OWN_DATA_DIRECTORY, DeepCompareMixin, SnapshotMixin, mksname +from tests import OWN_DATA_DIRECTORY, SCHEMA_TESTDATA_DIRECTORY, DeepCompareMixin, SnapshotMixin, mksname from tests._data.models import all_get_bom_funct_valid_immut, all_get_bom_funct_with_incomplete_deps +# only latest schema will have all data populated in serialized form +_LATEST_SUPPORTED_SCHEMA = SchemaVersion.V1_5 + @ddt class TestDeserializeJson(TestCase, SnapshotMixin, DeepCompareMixin): @@ -37,8 +40,7 @@ class TestDeserializeJson(TestCase, SnapshotMixin, DeepCompareMixin): @named_data(*all_get_bom_funct_valid_immut) @patch('cyclonedx.model.ThisTool._version', 'TESTING') def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: - # only latest schema will have all data populated in serialized form - snapshot_name = mksname(get_bom, SchemaVersion.V1_5, OutputFormat.JSON) + snapshot_name = mksname(get_bom, _LATEST_SUPPORTED_SCHEMA, OutputFormat.JSON) expected = get_bom() json = json_loads(self.readSnapshot(snapshot_name)) bom = Bom.from_json(json) diff --git a/tests/test_deserialize_xml.py b/tests/test_deserialize_xml.py index 1080f457..51323a24 100644 --- a/tests/test_deserialize_xml.py +++ b/tests/test_deserialize_xml.py @@ -16,6 +16,8 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. +from glob import iglob +from os.path import join from typing import Any, Callable from unittest import TestCase from unittest.mock import patch @@ -24,9 +26,14 @@ from cyclonedx.model.bom import Bom from cyclonedx.schema import OutputFormat, SchemaVersion -from tests import DeepCompareMixin, SnapshotMixin, mksname +from tests import SCHEMA_TESTDATA_DIRECTORY, DeepCompareMixin, SnapshotMixin, mksname from tests._data.models import all_get_bom_funct_valid_immut, all_get_bom_funct_with_incomplete_deps +# only latest schema will have all data populated in serialized form +_LATEST_SUPPORTED_SCHEMA = SchemaVersion.V1_5 + +_UNSUPPORTED_SCHEMA_VERSIONS = () + @ddt class TestDeserializeXml(TestCase, SnapshotMixin, DeepCompareMixin): @@ -34,10 +41,16 @@ class TestDeserializeXml(TestCase, SnapshotMixin, DeepCompareMixin): @named_data(*all_get_bom_funct_valid_immut) @patch('cyclonedx.model.ThisTool._version', 'TESTING') def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: - # only latest schema will have all data populated in serialized form - snapshot_name = mksname(get_bom, SchemaVersion.V1_5, OutputFormat.XML) + snapshot_name = mksname(get_bom, _LATEST_SUPPORTED_SCHEMA, OutputFormat.XML) expected = get_bom() with open(self.getSnapshotFile(snapshot_name), 'r') as s: bom = Bom.from_xml(s) self.assertBomDeepEqual(expected, bom, fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps) + + @named_data(*( + (sv, tf) for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS + for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'valid-*.json')) + )) + def test_schemaTestData(self) -> None: + Bom.from_xml(s) diff --git a/tests/test_enums.py b/tests/test_enums.py index ba5c6c5f..b492d2c6 100644 --- a/tests/test_enums.py +++ b/tests/test_enums.py @@ -44,7 +44,7 @@ from cyclonedx.schema import OutputFormat, SchemaVersion from cyclonedx.schema._res import BOM_JSON as SCHEMA_JSON, BOM_XML as SCHEMA_XML from cyclonedx.validation import make_schemabased_validator -from tests import SnapshotMixin +from tests import UNDEFINED_SCHEMA_VERSIONS, SnapshotMixin from tests._data.models import _make_bom # region SUT: all the enums @@ -111,16 +111,11 @@ def dp_cases_from_json_schemas(*jsonpointer: str) -> Generator[str, None, None]: yield from dp_cases_from_json_schema(sf, jsonpointer) -UNSUPPORTED_OF_SV = frozenset([ - (OutputFormat.JSON, SchemaVersion.V1_1), - (OutputFormat.JSON, SchemaVersion.V1_0), -]) - NAMED_OF_SV = tuple( (f'{of.name}-{sv.to_version()}', of, sv) for of in OutputFormat for sv in SchemaVersion - if (of, sv) not in UNSUPPORTED_OF_SV + if sv not in UNDEFINED_SCHEMA_VERSIONS.get(of, ()) ) diff --git a/tests/test_output_json.py b/tests/test_output_json.py index d4cb4553..1379eb30 100644 --- a/tests/test_output_json.py +++ b/tests/test_output_json.py @@ -31,16 +31,16 @@ from cyclonedx.output.json import BY_SCHEMA_VERSION, Json from cyclonedx.schema import OutputFormat, SchemaVersion from cyclonedx.validation.json import JsonStrictValidator -from tests import SnapshotMixin, mksname +from tests import UNDEFINED_SCHEMA_VERSIONS, SnapshotMixin, mksname from tests._data.models import all_get_bom_funct_invalid, all_get_bom_funct_valid, bom_all_same_bomref -UNSUPPORTED_SV = frozenset((SchemaVersion.V1_1, SchemaVersion.V1_0,)) +_UNDEFINED_SCHEMA_VERSIONS = UNDEFINED_SCHEMA_VERSIONS[OutputFormat.JSON] @ddt class TestOutputJson(TestCase, SnapshotMixin): - @data(*UNSUPPORTED_SV) + @data(*_UNDEFINED_SCHEMA_VERSIONS) def test_unsupported_schema_raises(self, sv: SchemaVersion) -> None: outputter_class = BY_SCHEMA_VERSION[sv] self.assertTrue(issubclass(outputter_class, Json)) @@ -51,7 +51,7 @@ def test_unsupported_schema_raises(self, sv: SchemaVersion) -> None: @named_data(*((f'{n}-{sv.to_version()}', gb, sv) for n, gb in all_get_bom_funct_valid for sv in SchemaVersion - if sv not in UNSUPPORTED_SV)) + if sv not in _UNDEFINED_SCHEMA_VERSIONS)) @unpack @patch('cyclonedx.model.ThisTool._version', 'TESTING') def test_valid(self, get_bom: Callable[[], Bom], sv: SchemaVersion, *_: Any, **__: Any) -> None: @@ -70,7 +70,7 @@ def test_valid(self, get_bom: Callable[[], Bom], sv: SchemaVersion, *_: Any, **_ @named_data(*((f'{n}-{sv.to_version()}', gb, sv) for n, gb in all_get_bom_funct_invalid for sv in SchemaVersion - if sv not in UNSUPPORTED_SV)) + if sv not in _UNDEFINED_SCHEMA_VERSIONS)) @unpack def test_invalid(self, get_bom: Callable[[], Bom], sv: SchemaVersion) -> None: bom = get_bom() diff --git a/tests/test_output_xml.py b/tests/test_output_xml.py index b477d28b..ec2725fd 100644 --- a/tests/test_output_xml.py +++ b/tests/test_output_xml.py @@ -21,21 +21,32 @@ from unittest.mock import Mock, patch from warnings import warn -from ddt import ddt, idata, named_data, unpack +from ddt import data, ddt, idata, named_data, unpack from cyclonedx.exception import CycloneDxException, MissingOptionalDependencyException from cyclonedx.exception.model import LicenseExpressionAlongWithOthersException, UnknownComponentDependencyException +from cyclonedx.exception.output import FormatNotSupportedException from cyclonedx.model.bom import Bom from cyclonedx.output.xml import BY_SCHEMA_VERSION, Xml from cyclonedx.schema import OutputFormat, SchemaVersion from cyclonedx.validation.xml import XmlValidator -from tests import SnapshotMixin, mksname +from tests import UNDEFINED_SCHEMA_VERSIONS, SnapshotMixin, mksname from tests._data.models import all_get_bom_funct_invalid, all_get_bom_funct_valid, bom_all_same_bomref +_UNDEFINED_SCHEMA_VERSIONS = UNDEFINED_SCHEMA_VERSIONS[OutputFormat.XML] + @ddt class TestOutputXml(TestCase, SnapshotMixin): + @data(*_UNDEFINED_SCHEMA_VERSIONS) + def test_unsupported_schema_raises(self, sv: SchemaVersion) -> None: + outputter_class = BY_SCHEMA_VERSION[sv] + self.assertTrue(issubclass(outputter_class, Xml)) + outputter = outputter_class(Mock(spec=Bom)) + with self.assertRaises(FormatNotSupportedException): + outputter.output_as_string() + @named_data(*( (f'{n}-{sv.to_version()}', gb, sv) for n, gb in all_get_bom_funct_valid for sv in SchemaVersion )) diff --git a/tests/test_validation.py b/tests/test_validation.py index 8755191a..96245824 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -24,20 +24,17 @@ from cyclonedx.schema import OutputFormat, SchemaVersion from cyclonedx.validation import make_schemabased_validator - -UNDEFINED_FORMAT_VERSION = { - (OutputFormat.JSON, SchemaVersion.V1_1), - (OutputFormat.JSON, SchemaVersion.V1_0), -} +from tests import UNDEFINED_SCHEMA_VERSIONS @ddt class TestGetSchemabasedValidator(TestCase): - @named_data(*([f'{f.name} {v.name}', f, v] - for f, v - in product(OutputFormat, SchemaVersion) - if (f, v) not in UNDEFINED_FORMAT_VERSION)) + @named_data( + *([f'{of.name} {sv.name}', of, sv] + for of, sv in product(OutputFormat, SchemaVersion) + if sv not in UNDEFINED_SCHEMA_VERSIONS.get(of, ())) + ) @unpack def test_as_expected(self, of: OutputFormat, sv: SchemaVersion) -> None: validator = make_schemabased_validator(of, sv) @@ -46,7 +43,9 @@ def test_as_expected(self, of: OutputFormat, sv: SchemaVersion) -> None: @data( *(('foo', sv, (ValueError, 'Unexpected output_format')) for sv in SchemaVersion), - *((f, v, (ValueError, 'Unsupported schema_version')) for f, v in UNDEFINED_FORMAT_VERSION) + *((of, sv, (ValueError, 'Unsupported schema_version')) + for of in UNDEFINED_SCHEMA_VERSIONS + for sv in UNDEFINED_SCHEMA_VERSIONS[of]) ) @unpack def test_fails_on_wrong_args(self, of: OutputFormat, sv: SchemaVersion, raises_regex: Tuple) -> None: diff --git a/tests/test_validation_json.py b/tests/test_validation_json.py index 6e99acb7..4a8f6347 100644 --- a/tests/test_validation_json.py +++ b/tests/test_validation_json.py @@ -25,14 +25,14 @@ from cyclonedx.exception import MissingOptionalDependencyException from cyclonedx.schema import OutputFormat, SchemaVersion from cyclonedx.validation.json import JsonStrictValidator, JsonValidator -from tests import SCHEMA_TESTDATA_DIRECTORY +from tests import SCHEMA_TESTDATA_DIRECTORY, UNDEFINED_SCHEMA_VERSIONS -UNSUPPORTED_SCHEMA_VERSIONS = {SchemaVersion.V1_0, SchemaVersion.V1_1, } +_UNDEFINED_SCHEMA_VERSIONS = UNDEFINED_SCHEMA_VERSIONS[OutputFormat.JSON] def _dp(prefix: str) -> Generator: return ( - (sv, tf) for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS + (sv, tf) for sv in SchemaVersion if sv not in _UNDEFINED_SCHEMA_VERSIONS for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'{prefix}-*.json')) ) @@ -40,13 +40,13 @@ def _dp(prefix: str) -> Generator: @ddt class TestJsonValidator(TestCase): - @idata(sv for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS) + @idata(sv for sv in SchemaVersion if sv not in _UNDEFINED_SCHEMA_VERSIONS) def test_validator_as_expected(self, schema_version: SchemaVersion) -> None: validator = JsonValidator(schema_version) self.assertIs(validator.schema_version, schema_version) self.assertIs(validator.output_format, OutputFormat.JSON) - @idata(UNSUPPORTED_SCHEMA_VERSIONS) + @idata(_UNDEFINED_SCHEMA_VERSIONS) def test_throws_with_unsupported_schema_version(self, schema_version: SchemaVersion) -> None: with self.assertRaisesRegex(ValueError, 'Unsupported schema_version'): JsonValidator(schema_version) @@ -80,7 +80,7 @@ def test_validate_expected_error(self, schema_version: SchemaVersion, test_data_ @ddt class TestJsonStrictValidator(TestCase): - @data(*UNSUPPORTED_SCHEMA_VERSIONS) + @data(*_UNDEFINED_SCHEMA_VERSIONS) def test_throws_with_unsupported_schema_version(self, schema_version: SchemaVersion) -> None: with self.assertRaisesRegex(ValueError, 'Unsupported schema_version'): JsonStrictValidator(schema_version) diff --git a/tests/test_validation_xml.py b/tests/test_validation_xml.py index c97ee6f7..d3f10663 100644 --- a/tests/test_validation_xml.py +++ b/tests/test_validation_xml.py @@ -25,14 +25,14 @@ from cyclonedx.exception import MissingOptionalDependencyException from cyclonedx.schema import OutputFormat, SchemaVersion from cyclonedx.validation.xml import XmlValidator -from tests import SCHEMA_TESTDATA_DIRECTORY +from tests import SCHEMA_TESTDATA_DIRECTORY, UNDEFINED_SCHEMA_VERSIONS -UNSUPPORTED_SCHEMA_VERSIONS = set() +_UNDEFINED_SCHEMA_VERSIONS = UNDEFINED_SCHEMA_VERSIONS[OutputFormat.XML] def _dp(prefix: str) -> Generator: return ( - (sv, tf) for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS + (sv, tf) for sv in SchemaVersion if sv not in _UNDEFINED_SCHEMA_VERSIONS for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'{prefix}-*.xml')) ) @@ -40,13 +40,13 @@ def _dp(prefix: str) -> Generator: @ddt class TestXmlValidator(TestCase): - @idata(sv for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS) + @idata(sv for sv in SchemaVersion if sv not in _UNDEFINED_SCHEMA_VERSIONS) def test_validator_as_expected(self, schema_version: SchemaVersion) -> None: validator = XmlValidator(schema_version) self.assertIs(validator.schema_version, schema_version) self.assertIs(validator.output_format, OutputFormat.XML) - @idata(UNSUPPORTED_SCHEMA_VERSIONS) + @idata(_UNDEFINED_SCHEMA_VERSIONS) def test_throws_with_unsupported_schema_version(self, schema_version: SchemaVersion) -> None: with self.assertRaisesRegex(ValueError, f'unsupported schema_version: {schema_version}'): XmlValidator(schema_version) From 7920dbbd1d22123f30db631b57f2858ab3218bd1 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 25 Jan 2024 18:16:49 +0100 Subject: [PATCH 2/2] tests Signed-off-by: Jan Kowalleck --- tests/__init__.py | 3 +++ tests/test_deserialize_json.py | 28 +++++++++++++++++++++++----- tests/test_deserialize_xml.py | 27 ++++++++++++++++++--------- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 8bcae6b3..a7502771 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -42,6 +42,9 @@ OutputFormat.JSON: {SchemaVersion.V1_0, SchemaVersion.V1_1, }, } +LATEST_SUPPORTED_SCHEMA = SchemaVersion.V1_5 + + RECREATE_SNAPSHOTS = '1' == getenv('CDX_TEST_RECREATE_SNAPSHOTS') if RECREATE_SNAPSHOTS: print('!!! WILL RECREATE ALL SNAPSHOTS !!!') diff --git a/tests/test_deserialize_json.py b/tests/test_deserialize_json.py index 1f657ad7..ff4a967a 100644 --- a/tests/test_deserialize_json.py +++ b/tests/test_deserialize_json.py @@ -16,8 +16,9 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. +from glob import iglob from json import loads as json_loads -from os.path import join +from os.path import basename, join from typing import Any, Callable from unittest import TestCase from unittest.mock import patch @@ -27,11 +28,18 @@ from cyclonedx.model.bom import Bom from cyclonedx.model.license import DisjunctiveLicense, LicenseExpression, LicenseRepository from cyclonedx.schema import OutputFormat, SchemaVersion -from tests import OWN_DATA_DIRECTORY, SCHEMA_TESTDATA_DIRECTORY, DeepCompareMixin, SnapshotMixin, mksname +from tests import ( + LATEST_SUPPORTED_SCHEMA, + OWN_DATA_DIRECTORY, + SCHEMA_TESTDATA_DIRECTORY, + UNDEFINED_SCHEMA_VERSIONS, + DeepCompareMixin, + SnapshotMixin, + mksname, +) from tests._data.models import all_get_bom_funct_valid_immut, all_get_bom_funct_with_incomplete_deps -# only latest schema will have all data populated in serialized form -_LATEST_SUPPORTED_SCHEMA = SchemaVersion.V1_5 +_UNDEFINED_SCHEMA_VERSIONS = UNDEFINED_SCHEMA_VERSIONS[OutputFormat.JSON] @ddt @@ -40,7 +48,8 @@ class TestDeserializeJson(TestCase, SnapshotMixin, DeepCompareMixin): @named_data(*all_get_bom_funct_valid_immut) @patch('cyclonedx.model.ThisTool._version', 'TESTING') def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: - snapshot_name = mksname(get_bom, _LATEST_SUPPORTED_SCHEMA, OutputFormat.JSON) + # only latest schema will have all data populated in serialized form + snapshot_name = mksname(get_bom, LATEST_SUPPORTED_SCHEMA, OutputFormat.JSON) expected = get_bom() json = json_loads(self.readSnapshot(snapshot_name)) bom = Bom.from_json(json) @@ -73,3 +82,12 @@ def test(ls: LicenseRepository) -> None: test(bom.metadata.component.licenses) test(list(bom.components)[0].licenses) test(list(bom.services)[0].licenses) + + @named_data(*( + (f'{sv.name}/{basename(tf)}', tf) + for sv in SchemaVersion if sv not in _UNDEFINED_SCHEMA_VERSIONS + for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'valid-*.json')) + )) + def test_schemaTestData(self, tf: str) -> None: + with open(tf, 'r') as s: + Bom.from_json(json_loads(s.read())) diff --git a/tests/test_deserialize_xml.py b/tests/test_deserialize_xml.py index 51323a24..3d352fdc 100644 --- a/tests/test_deserialize_xml.py +++ b/tests/test_deserialize_xml.py @@ -17,7 +17,7 @@ from glob import iglob -from os.path import join +from os.path import basename, join from typing import Any, Callable from unittest import TestCase from unittest.mock import patch @@ -26,13 +26,19 @@ from cyclonedx.model.bom import Bom from cyclonedx.schema import OutputFormat, SchemaVersion -from tests import SCHEMA_TESTDATA_DIRECTORY, DeepCompareMixin, SnapshotMixin, mksname +from tests import ( + LATEST_SUPPORTED_SCHEMA, + SCHEMA_TESTDATA_DIRECTORY, + UNDEFINED_SCHEMA_VERSIONS, + DeepCompareMixin, + SnapshotMixin, + mksname, +) from tests._data.models import all_get_bom_funct_valid_immut, all_get_bom_funct_with_incomplete_deps # only latest schema will have all data populated in serialized form -_LATEST_SUPPORTED_SCHEMA = SchemaVersion.V1_5 -_UNSUPPORTED_SCHEMA_VERSIONS = () +_UNDEFINED_SCHEMA_VERSIONS = UNDEFINED_SCHEMA_VERSIONS[OutputFormat.XML] @ddt @@ -41,7 +47,8 @@ class TestDeserializeXml(TestCase, SnapshotMixin, DeepCompareMixin): @named_data(*all_get_bom_funct_valid_immut) @patch('cyclonedx.model.ThisTool._version', 'TESTING') def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: - snapshot_name = mksname(get_bom, _LATEST_SUPPORTED_SCHEMA, OutputFormat.XML) + # only latest schema will have all data populated in serialized form + snapshot_name = mksname(get_bom, LATEST_SUPPORTED_SCHEMA, OutputFormat.XML) expected = get_bom() with open(self.getSnapshotFile(snapshot_name), 'r') as s: bom = Bom.from_xml(s) @@ -49,8 +56,10 @@ def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps) @named_data(*( - (sv, tf) for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS - for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'valid-*.json')) + (f'{sv.name}/{basename(tf)}', tf) + for sv in SchemaVersion if sv not in _UNDEFINED_SCHEMA_VERSIONS + for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'valid-*.xml')) )) - def test_schemaTestData(self) -> None: - Bom.from_xml(s) + def test_schemaTestData(self, tf: str) -> None: + with open(tf, 'r') as s: + Bom.from_xml(s)