Skip to content

Commit

Permalink
updated test_tags.py to align with new tags.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Sankalp Gilda committed Oct 7, 2024
1 parent 2d4af60 commit 1c8e284
Showing 1 changed file with 207 additions and 32 deletions.
239 changes: 207 additions & 32 deletions src/tsbootstrap/registry/tests/test_tags.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,221 @@
"""Tests for tag register an tag functionality."""
"""
Tests for the tag registry and tag validation functionality.
from tsbootstrap.registry._tags import OBJECT_TAG_REGISTER
This module contains tests to ensure that the `OBJECT_TAG_REGISTER` is correctly
configured and that each tag adheres to the specified structure and type constraints.
"""

from tsbootstrap.registry._tags import OBJECT_TAG_REGISTER, Tag


def test_tag_register_type():
"""Test the specification of the tag register. See _tags for specs."""
"""
Test the specification of the tag register.
Ensures that `OBJECT_TAG_REGISTER` is a list of `Tag` instances with the correct attributes and types.
Raises
------
TypeError
If `OBJECT_TAG_REGISTER` is not a list or contains non-`Tag` instances.
ValueError
If any `Tag` instance does not conform to the expected structure or type constraints.
"""
# Verify that OBJECT_TAG_REGISTER is a list
if not isinstance(OBJECT_TAG_REGISTER, list):
raise TypeError("OBJECT_TAG_REGISTER is not a list.")
if not all(isinstance(tag, tuple) for tag in OBJECT_TAG_REGISTER):
raise TypeError("Not all elements in OBJECT_TAG_REGISTER are tuples.")
raise TypeError("`OBJECT_TAG_REGISTER` is not a list.")

# Verify that all elements in OBJECT_TAG_REGISTER are instances of Tag
if not all(isinstance(tag, Tag) for tag in OBJECT_TAG_REGISTER):
raise TypeError(
"Not all elements in `OBJECT_TAG_REGISTER` are `Tag` instances."
)

# Iterate through each Tag instance to validate its attributes
for tag in OBJECT_TAG_REGISTER:
if len(tag) != 4:
raise ValueError("Tag does not have 4 elements.")
if not isinstance(tag[0], str):
raise TypeError("Tag name is not a string.")
if not isinstance(tag[1], (str, list)):
raise TypeError("Tag type is not a string or list.")
if isinstance(tag[1], list) and not all(
isinstance(x, str) for x in tag[1]
):
raise TypeError("Not all elements in tag type list are strings.")
if not isinstance(tag[2], (str, tuple)):
raise TypeError("Tag description is not a string or tuple.")
if isinstance(tag[2], tuple):
if not len(tag[2]) == 2:
# Validate the 'name' attribute
if not isinstance(tag.name, str):
raise TypeError(f"Tag name '{tag.name}' is not a string.")

# Validate the 'scitype' attribute
if not isinstance(tag.scitype, str):
raise TypeError(f"Tag scitype '{tag.scitype}' is not a string.")

# Validate the 'value_type' attribute
if not isinstance(tag.value_type, (str, tuple)):
raise TypeError(
f"Tag value_type '{tag.value_type}' is not a string or tuple."
)

if isinstance(tag.value_type, tuple):
if len(tag.value_type) != 2:
raise ValueError(
"Tag description tuple does not have 2 elements."
"Tuple `value_type` must have exactly two elements."
)
if not isinstance(tag[2][0], str):
raise TypeError(
"Tag description tuple first element is not a string."

base_type, subtype = tag.value_type

# Validate the base type
if base_type not in {"str", "list"}:
raise ValueError(
f"First element of `value_type` tuple must be 'str' or 'list', got '{base_type}'."
)
if not isinstance(tag[2][1], (list, str)):
raise TypeError(
"Tag description tuple second element is not a list or string."

# Validate the subtype based on the base type
if base_type == "str":
if not isinstance(subtype, list) or not all(
isinstance(item, str) for item in subtype
):
raise TypeError(
"Second element of `value_type` tuple must be a list of strings when base is 'str'."
)
elif base_type == "list" and not (
(
isinstance(subtype, list)
and all(isinstance(item, str) for item in subtype)
)
if isinstance(tag[2][1], list) and not all(
isinstance(x, str) for x in tag[2][1]
or isinstance(subtype, str)
):
raise TypeError(
"Not all elements in tag description list are strings."
"Second element of `value_type` tuple must be a list of strings or 'str' when base is 'list'."
)

# Validate the 'description' attribute
if not isinstance(tag.description, str):
raise TypeError(
f"Tag description '{tag.description}' is not a string."
)


def test_object_tag_table_structure():
"""
Test the structure of `OBJECT_TAG_TABLE`.
Ensures that `OBJECT_TAG_TABLE` is a list of dictionaries, each containing the expected keys and corresponding types.
Raises
------
TypeError
If `OBJECT_TAG_TABLE` is not a list or contains elements that are not dictionaries.
KeyError
If any dictionary in `OBJECT_TAG_TABLE` is missing required keys.
TypeError
If any value in the dictionaries does not match the expected type.
"""
from tsbootstrap.registry._tags import OBJECT_TAG_TABLE

# Define the expected keys and their types
expected_keys = {
"name": str,
"scitype": str,
"value_type": (str, tuple),
"description": str,
}

# Verify that OBJECT_TAG_TABLE is a list
if not isinstance(OBJECT_TAG_TABLE, list):
raise TypeError("`OBJECT_TAG_TABLE` is not a list.")

# Iterate through each dictionary in OBJECT_TAG_TABLE to validate its structure
for entry in OBJECT_TAG_TABLE:
# Verify that each entry is a dictionary
if not isinstance(entry, dict):
raise TypeError(
"Each entry in `OBJECT_TAG_TABLE` must be a dictionary."
)

# Check for the presence of all expected keys
for key, expected_type in expected_keys.items():
if key not in entry:
raise KeyError(
f"Key '{key}' is missing from an entry in `OBJECT_TAG_TABLE`."
)

# Validate the type of each value
if not isinstance(entry[key], expected_type):
raise TypeError(
f"Value for key '{key}' in `OBJECT_TAG_TABLE` entry is not of type {
expected_type}."
)


def test_object_tag_list():
"""
Test the contents of `OBJECT_TAG_LIST`.
Ensures that `OBJECT_TAG_LIST` contains all tag names present in `OBJECT_TAG_REGISTER` and that each name is a string.
Raises
------
TypeError
If `OBJECT_TAG_LIST` is not a list or contains non-string elements.
ValueError
If any tag name in `OBJECT_TAG_register` is missing from `OBJECT_TAG_LIST`.
"""
from tsbootstrap.registry._tags import OBJECT_TAG_LIST

# Verify that OBJECT_TAG_LIST is a list
if not isinstance(OBJECT_TAG_LIST, list):
raise TypeError("`OBJECT_TAG_LIST` is not a list.")

# Verify that all elements in OBJECT_TAG_LIST are strings
if not all(isinstance(name, str) for name in OBJECT_TAG_LIST):
raise TypeError("All elements in `OBJECT_TAG_LIST` must be strings.")

# Extract all tag names from OBJECT_TAG_REGISTER
tag_names = {tag.name for tag in OBJECT_TAG_REGISTER}

# Verify that OBJECT_TAG_LIST contains all tag names
missing_tags = tag_names - set(OBJECT_TAG_LIST)
if missing_tags:
raise ValueError(
f"The following tags are missing from `OBJECT_TAG_LIST`: {missing_tags}"
)


def test_check_tag_is_valid():
"""
Test the `check_tag_is_valid` function.
Ensures that `check_tag_is_valid` correctly validates tag values based on their expected types.
Raises
------
AssertionError
If any test case fails.
"""
from tsbootstrap.registry._tags import check_tag_is_valid

# Define test cases as tuples of (tag_name, tag_value, expected_result)
test_cases = [
("object_type", "regressor", True),
("object_type", "invalid_type", False),
("capability:multivariate", True, True),
("capability:multivariate", False, True),
("capability:multivariate", "yes", False),
("python_version", "3.8.5", True),
("python_version", 3.8, False),
("python_dependencies", ["numpy", "pandas"], True),
("python_dependencies", "numpy", True),
("python_dependencies", ["numpy", 123], False),
("python_dependencies_alias", {"numpy": "np"}, True),
("python_dependencies_alias", "numpy", False),
("non_existent_tag", "value", False), # Should raise KeyError
]

for tag_name, tag_value, expected in test_cases:
if tag_name == "non_existent_tag":
try:
check_tag_is_valid(tag_name, tag_value)
raise AssertionError(
f"Expected KeyError for tag '{tag_name}', but no error was raised."
)
except KeyError:
pass # Expected behavior
else:
result = check_tag_is_valid(tag_name, tag_value)
if result != expected:
raise ValueError(
f"check_tag_is_valid({tag_name!r}, {tag_value!r}) returned {
result}, expected {expected}."
)
if not isinstance(tag[3], str):
raise TypeError("Tag source is not a string.")

0 comments on commit 1c8e284

Please sign in to comment.