Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion spec_tests/test_hed_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ def setUpClass(cls):
cls.saved_cache_folder = hed_cache.HED_CACHE_DIRECTORY
schema.set_cache_directory(cls.hed_cache_dir)

cls.default_xml_base_filename = "HED8.0.0t.xml"
cls.hed_test_version = "7.1.1"
cls.hed_invalid_version = "4.6.7"

Expand Down
6,538 changes: 0 additions & 6,538 deletions tests/data/schema_tests/HED8.0.0t.xml

This file was deleted.

7,072 changes: 0 additions & 7,072 deletions tests/data/schema_tests/HED8.1.0.xml

This file was deleted.

1,304 changes: 0 additions & 1,304 deletions tests/data/schema_tests/HED8.2.0.mediawiki

This file was deleted.

7,296 changes: 0 additions & 7,296 deletions tests/data/schema_tests/HED8.2.0.xml

This file was deleted.

23 changes: 23 additions & 0 deletions tests/data/schema_tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Schema test data

Tests load released standard schemas from the copies bundled with hedtools in `hed/schema/schema_data/`, with
`load_schema_version("8.2.0")`, never from a copy here. A test that needs the file itself uses
`bundled_standard_path` in `tests/schema/schema_test_helpers.py`. A test that names a released standard inside
an `xml_folder` (a version string is looked up only in that folder) builds a temporary folder with
`make_xml_folder` in the same module. `load_schema_version` returns one shared cached object per version, so a
test that changes its schema works on a `copy.deepcopy`.

## Full standard schemas kept as files

Each is released 8.0.0 with a deliberate edit, so the bundle cannot replace it:

- `HED8.0.0_2_value_classes.xml` - a tag with two value classes (edge-case format roundtrip test).
- `unknown_attribute.xml` - attributes the schema does not define (edge-case format roundtrip test).
- `HED8.0.0_2_value_classes.mediawiki`, `unknown_attribute.mediawiki` - the MediaWiki sources of the two above;
no test reads them.
- `../validator_tests/HED8.0.0_added_tests.mediawiki` - test additions for the validator tests (for example
`Item/Currency-test`).

Everything else here is a small edited fixture or fragment (`added_prop*`, `duplicate_unit*`,
`prologue_tests/`, `wiki_tests/`, `prerelease/` stubs) or a test library (`merge_tests/`,
`merge_group_tests/`, `HED_test*`).
13,607 changes: 0 additions & 13,607 deletions tests/data/schema_tests/merge_group_tests/HED8.4.0.xml

This file was deleted.

13,993 changes: 0 additions & 13,993 deletions tests/data/schema_tests/merge_group_tests/HED8.5.0.xml

This file was deleted.

15 changes: 6 additions & 9 deletions tests/data/schema_tests/merge_group_tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
Test-only library schemas for the schema merge-group tests
(`tests/schema/test_schema_merge.py`), copied from hed-tests
`json_test_data/test_schemas/<library>/hedxml_unmerged/` at hed-tests commit
ccfb308, plus the two vendored standard schemas (`HED8.4.0.xml`,
`HED8.5.0.xml`) from that repository's `json_test_data/test_schemas/hedxml/`
folder so that loading is hermetic. `HED8.5.0.xml` is a prerelease snapshot: refreshed 2026-09-13 from
hed-schemas `standard_schema/prerelease/HED8.5.0.xml` at hed-schemas commit
c049843 (anyUnits and Quantity; via hed-tests `convert_test_schemas.py --refresh`,
hed-tests PR #56, merged as 0f2afd4); re-copy it when
8.5.0 is released and keep the vendored copy after that. The libraries are in UNMERGED form and use the cache-convention
file names, so this folder can be passed as `xml_folder` to
`load_schema_version`. See the hed-tests README in that folder for what each
ccfb308. The libraries are in UNMERGED form and use the cache-convention file
names. Their partner standards (8.4.0 and 8.5.0) are not copied here: the tests
build a temporary `xml_folder` from this folder plus the copies bundled with
hedtools in `hed/schema/schema_data/` (`make_xml_folder` in
`tests/schema/schema_test_helpers.py`), so loading stays hermetic. When
re-copying from hed-tests, do not copy its `HED8.*.xml` standards back in. See the hed-tests README in that folder for what each
library version probes; the `.mediawiki` sources there are the source of
truth and are regenerated with `src/scripts/convert_test_schemas.py`.
7,296 changes: 0 additions & 7,296 deletions tests/data/schema_tests/merge_tests/HED8.2.0.xml

This file was deleted.

5 changes: 1 addition & 4 deletions tests/models/test_base_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,13 @@ def setUpClass(cls):
bids_root_path = os.path.realpath(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/bids_tests/eeg_ds003645s_hed")
)
schema_path = os.path.realpath(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/schema_tests/HED8.2.0.xml")
)
cls.bids_root_path = bids_root_path
json_path = os.path.realpath(os.path.join(bids_root_path, "task-FacePerception_events.json"))
events_path = os.path.realpath(
os.path.join(bids_root_path, "sub-002/eeg/sub-002_task-FacePerception_run-1_events.tsv")
)

cls.hed_schema = schema.load_schema(schema_path)
cls.hed_schema = schema.load_schema_version("8.2.0")
sidecar1 = Sidecar(json_path, name="face_sub1_json")
mapper1 = ColumnMapper(sidecar=sidecar1, optional_tag_columns=["HED"], warn_on_missing_column=False)
cls.input_data1 = BaseInput(
Expand Down
7 changes: 2 additions & 5 deletions tests/models/test_column_mapper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import unittest

from hed import load_schema
from hed import load_schema_version
from hed.errors import ValidationErrors
from hed.models import ColumnType, HedString
from hed.models.column_mapper import ColumnMapper
Expand All @@ -11,10 +11,7 @@
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
base_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/")
schema_file = "schema_tests/HED8.0.0t.xml"

cls.hed_schema = load_schema(os.path.join(base_data_dir, schema_file))
cls.hed_schema = load_schema_version("8.0.0")
cls.integer_key_dictionary = {0: "one", 1: "two", 2: "three"}
cls.zero_based_row_column_count = 3
cls.column_prefix_dictionary = {2: "Event/Description/", 3: "Event/Label/", 4: "Event/Category/"}
Expand Down
3 changes: 1 addition & 2 deletions tests/models/test_hed_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.base_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/")
hed_xml_file = os.path.join(cls.base_data_dir, "schema_tests/HED8.0.0t.xml")
cls.hed_schema = schema.load_schema(hed_xml_file)
cls.hed_schema = schema.load_schema_version("8.0.0")

def test_remove_groups(self):
from hed.models.definition_dict import DefTagNames
Expand Down
3 changes: 1 addition & 2 deletions tests/models/test_query_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ class TestParser(unittest.TestCase):
def setUpClass(cls):
base_data_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../data/"))
cls.base_data_dir = base_data_dir
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
cls.hed_schema = schema.load_schema(hed_xml_file)
cls.hed_schema = schema.load_schema_version("8.0.0")

def base_test(self, parse_expr, search_strings):
expression = QueryHandler(parse_expr)
Expand Down
5 changes: 1 addition & 4 deletions tests/models/test_query_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Tests for query_service module: get_query_handlers and search_hed_objs."""

import os
import unittest

from hed import schema
Expand Down Expand Up @@ -79,9 +78,7 @@ class TestSearchHedObjs(unittest.TestCase):

@classmethod
def setUpClass(cls):
base_data_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../data/"))
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
cls.hed_schema = schema.load_schema(hed_xml_file)
cls.hed_schema = schema.load_schema_version("8.0.0")

def test_basic_search(self):
hed_objs = [
Expand Down
5 changes: 1 addition & 4 deletions tests/models/test_query_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
- children = [Red] (only the matched tag)
"""

import os
import unittest
from unittest.mock import Mock

Expand Down Expand Up @@ -300,9 +299,7 @@ class TestSearchResultGroupIdentitySemantics(unittest.TestCase):

@classmethod
def setUpClass(cls):
base_data_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../data/"))
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
cls.hed_schema = schema.load_schema(hed_xml_file)
cls.hed_schema = schema.load_schema_version("8.0.0")

def setUp(self):
# Two HedStrings with identical content parsed independently.
Expand Down
8 changes: 2 additions & 6 deletions tests/models/test_schema_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ class TestSchemaLookupBase(unittest.TestCase):

@classmethod
def setUpClass(cls):
base_data_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../data/"))
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
try:
from hed import schema as hed_schema

cls.hed_schema = hed_schema.load_schema(hed_xml_file)
cls.hed_schema = hed_schema.load_schema_version("8.0.0")
cls.lookup = generate_schema_lookup(cls.hed_schema)
except Exception as exc:
cls.hed_schema = None
Expand Down Expand Up @@ -194,13 +192,11 @@ class TestGenerateSchemaLookupGroup(unittest.TestCase):

@classmethod
def setUpClass(cls):
base_data_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../data/"))
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
try:
from hed import schema as hed_schema
from hed.schema.hed_schema_group import HedSchemaGroup

single = hed_schema.load_schema(hed_xml_file)
single = hed_schema.load_schema_version("8.0.0")
cls.group = HedSchemaGroup([single])
cls.single_lookup = generate_schema_lookup(single)
cls.group_lookup = generate_schema_lookup(cls.group)
Expand Down
3 changes: 1 addition & 2 deletions tests/models/test_sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ class Test(unittest.TestCase):
def setUpClass(cls):
base_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/")
cls.base_data_dir = base_data_dir
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
cls.hed_schema = schema.load_schema(hed_xml_file)
cls.hed_schema = schema.load_schema_version("8.0.0")
json_filename = os.path.join(base_data_dir, "sidecar_tests/both_types_events.json")
cls.json_filename = json_filename
json_def_filename = os.path.join(base_data_dir, "sidecar_tests/both_types_events_with_defs.json")
Expand Down
3 changes: 1 addition & 2 deletions tests/models/test_spreadsheet_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ class Test(unittest.TestCase):
def setUpClass(cls):
base = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/")
cls.base_data_dir = base
hed_xml_file = os.path.join(base, "schema_tests/HED8.0.0t.xml")
cls.hed_schema = schema.load_schema(hed_xml_file)
cls.hed_schema = schema.load_schema_version("8.0.0")
default = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "../data/spreadsheet_validator_tests/ExcelMultipleSheets.xlsx"
)
Expand Down
5 changes: 1 addition & 4 deletions tests/models/test_string_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
schema lookup table from a real schema file.
"""

import os
import unittest

import pandas as pd
Expand Down Expand Up @@ -982,12 +981,10 @@ class TestSchemaLookupAncestorSearch(unittest.TestCase):

@classmethod
def setUpClass(cls):
base_data_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "../data/"))
hed_xml_file = os.path.join(base_data_dir, "schema_tests/HED8.0.0t.xml")
try:
from hed import schema as hed_schema

cls.hed_schema = hed_schema.load_schema(hed_xml_file)
cls.hed_schema = hed_schema.load_schema_version("8.0.0")
cls.lookup = generate_schema_lookup(cls.hed_schema)
except Exception:
cls.hed_schema = None
Expand Down
5 changes: 1 addition & 4 deletions tests/models/test_tabular_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ def setUpClass(cls):
bids_root_path = os.path.realpath(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/bids_tests/eeg_ds003645s_hed")
)
schema_path = os.path.realpath(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/schema_tests/HED8.2.0.xml")
)
sidecar1_path = os.path.realpath(os.path.join(bids_root_path, "task-FacePerception_events.json"))
cls.events_path = os.path.realpath(
os.path.join(bids_root_path, "sub-002/eeg/sub-002_task-FacePerception_run-1_events.tsv")
Expand All @@ -29,7 +26,7 @@ def setUpClass(cls):
os.path.dirname(os.path.realpath(__file__)), "../data/other_tests/task-FacePerceptionSmall_events.json"
)
)
cls.hed_schema = schema.load_schema(schema_path)
cls.hed_schema = schema.load_schema_version("8.2.0")
cls.sidecar1 = Sidecar(sidecar1_path, name="face_sub1_json")
cls.sidecar2 = Sidecar(sidecar2_path, name="face_small_json")
cls.base_output_folder = base_output_folder
Expand Down
46 changes: 45 additions & 1 deletion tests/schema/schema_test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""
Shared utility functions for schema tests.

Provides helper decorators and functions for creating temporary files in tests.
Provides helper decorators and functions for creating temporary files and schema folders in tests.
"""

import functools
import os
import shutil
import tempfile

from hed import schema


def get_temp_filename(extension):
"""
Expand Down Expand Up @@ -57,3 +60,44 @@ def wrapper(*args, **kwargs):
return wrapper

return decorator


def bundled_standard_path(version):
"""
Return the path of a released standard schema bundled with hedtools.

Parameters:
version (str): A released standard version (e.g., "8.4.0").

Returns:
str: Path to the bundled XML file in hed/schema/schema_data.
"""
return os.path.join(os.path.dirname(schema.__file__), "schema_data", f"HED{version}.xml")


def make_xml_folder(versions, copies=()):
"""
Build a temporary folder to pass as xml_folder: fixture files plus bundled standard schemas.

A version string loaded with xml_folder is looked up only in that folder, so a test that names a
released standard there needs the file on disk; it comes from the bundle instead of a copy in tests/data.

Parameters:
versions (list[str]): Released standard versions copied from the bundle into the folder root.
copies (list[tuple[str, str]]): (source, target) pairs; a source file or folder is copied into the
target subfolder ("" for the root).

Returns:
str: Path to the new folder; the caller removes it with shutil.rmtree.
"""
folder = tempfile.mkdtemp()
for source, target in copies:
destination = os.path.join(folder, target)
if os.path.isdir(source):
shutil.copytree(source, destination, dirs_exist_ok=True)
else:
os.makedirs(destination, exist_ok=True)
shutil.copy(source, destination)
for version in versions:
shutil.copy(bundled_standard_path(version), folder)
return folder
8 changes: 3 additions & 5 deletions tests/schema/test_base_tag.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import os
import unittest

from hed.errors import ErrorHandler
from hed.models import HedString
from hed.schema import load_schema
from hed.schema import load_schema_version


class TestBaseTagBase(unittest.TestCase):
schema_file = "../data/schema_tests/HED8.0.0t.xml"
schema_version = "8.0.0"

@classmethod
def setUpClass(cls):
hed_xml = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.schema_file)
cls.hed_schema = load_schema(hed_xml)
cls.hed_schema = load_schema_version(cls.schema_version)
cls.error_handler = ErrorHandler()

def tag_form_base(self, test_strings, expected_results, expected_errors):
Expand Down
2 changes: 1 addition & 1 deletion tests/schema/test_convert_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


class TestTagFormat(TestHedBase):
schema_file = "../data/schema_tests/HED8.0.0t.xml"
schema_version = "8.0.0"


class TestConvertTag(TestTagFormat):
Expand Down
10 changes: 3 additions & 7 deletions tests/schema/test_hed_schema.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import os
import unittest

import hed
from hed.errors import HedFileError
from hed.models import HedTag
from hed.schema import HedKey, HedSchemaGroup, get_hed_xml_version, load_schema, load_schema_version


class TestHedSchema(unittest.TestCase):
schema_file_3g_xml = "../data/schema_tests/HED8.0.0t.xml"
schema_file_3g = "../data/schema_tests/HED8.2.0.mediawiki"

@classmethod
def setUpClass(cls):
cls.hed_xml_3g = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.schema_file_3g_xml)
cls.hed_wiki_3g = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.schema_file_3g)
cls.hed_schema_3g_wiki = load_schema(cls.hed_wiki_3g)
cls.hed_schema_3g = load_schema(cls.hed_xml_3g)
cls.hed_xml_3g = os.path.join(os.path.dirname(hed.schema.__file__), "schema_data", "HED8.0.0.xml")
cls.hed_schema_3g = load_schema_version("8.0.0")

schema_file = "../data/validator_tests/HED8.0.0_added_tests.mediawiki"
hed_xml = os.path.join(os.path.dirname(os.path.realpath(__file__)), schema_file)
Expand Down
21 changes: 15 additions & 6 deletions tests/schema/test_hed_schema_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from hed.errors.error_types import SchemaErrors
from hed.schema import HedKey, HedSchema, HedSchemaGroup, hed_cache, load_schema, load_schema_version
from hed.schema.hed_schema_io import _load_schema_version, from_string, parse_version_list
from tests.schema.schema_test_helpers import get_temp_filename, with_temp_file
from tests.schema.schema_test_helpers import get_temp_filename, make_xml_folder, with_temp_file
from tests.schema.util_test_schemas import TEST_SCHEMAS_DIR, load_test_schema, test_schemas_available


Expand Down Expand Up @@ -50,9 +50,7 @@ def test_load_schema_invalid_parameters(self):
load_schema(bad_filename)

def test_load_schema_name(self):
schema_path = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "../data/schema_tests/HED8.2.0.mediawiki"
)
schema_path = os.path.join(os.path.dirname(schema.__file__), "schema_data", "HED8.2.0.xml")

hed_schema = load_schema(schema_path, schema_namespace="testspace", name="Test Name")
self.assertEqual(hed_schema.schema_namespace, "testspace:")
Expand Down Expand Up @@ -1098,8 +1096,19 @@ class TestPrereleaseSchemaLoading(unittest.TestCase):

@classmethod
def setUpClass(cls):
"""Set up test fixtures."""
cls.schema_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/schema_tests/")
"""Set up test fixtures: the bundled 8.2.0 at the root beside the fixture schemas."""
fixtures = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/schema_tests/")
cls.schema_dir = make_xml_folder(
["8.2.0"],
[
(os.path.join(fixtures, "HED_testlocal_2.1.0.xml"), ""),
(os.path.join(fixtures, "prerelease"), "prerelease"),
],
)

@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.schema_dir, ignore_errors=True)

def test_load_regular_schema(self):
"""Test that a regular schema loads correctly."""
Expand Down
Loading
Loading