tests and agents.md

This commit is contained in:
2026-08-25 17:54:13 +02:00
parent c46b37f88e
commit f575a84c13
5 changed files with 288 additions and 63 deletions
+104
View File
@@ -8,6 +8,7 @@ from unittest.mock import patch
from introspect import (
FunctionData,
description_hints_nullable,
infer_getter_return_types,
parse_rst_function_sig,
infer_context_member_type,
@@ -19,6 +20,7 @@ from introspect import (
introspect_screen_context_members,
parse_docstring_types,
python_type_name,
rna_property_to_type,
)
@@ -650,5 +652,107 @@ class TestRuntimeEdgeCases(unittest.TestCase):
self.assertEqual(data["variables"], [])
class TestRnaPropertyToType(unittest.TestCase):
def test_enum_flag_is_set_of_str(self) -> None:
prop = SimpleNamespace(type="enum", is_enum_flag=True, fixed_type=None)
self.assertEqual(rna_property_to_type(prop), "set[str]")
def test_enum_scalar_with_items_is_literal(self) -> None:
prop = SimpleNamespace(
type="enum",
is_enum_flag=False,
fixed_type=None,
enum_items=[
("NONE", "", ""),
("LEFTMOUSE", "", ""),
("RIGHTMOUSE", "", ""),
],
)
self.assertEqual(
rna_property_to_type(prop),
'Literal["NONE", "LEFTMOUSE", "RIGHTMOUSE"]',
)
def test_enum_scalar_with_empty_items_is_str(self) -> None:
# Dynamic enums (items computed at runtime) have empty enum_items.
prop = SimpleNamespace(
type="enum", is_enum_flag=False, fixed_type=None, enum_items=[]
)
self.assertEqual(rna_property_to_type(prop), "str")
def test_enum_without_flag_attr_is_str(self) -> None:
prop = SimpleNamespace(type="enum", fixed_type=None)
self.assertEqual(rna_property_to_type(prop), "str")
def test_pointer_nullable_when_not_never_none(self) -> None:
prop = SimpleNamespace(
type="pointer",
fixed_type=SimpleNamespace(identifier="Area"),
is_never_none=False,
)
self.assertEqual(rna_property_to_type(prop), "Area | None")
def test_pointer_non_nullable_when_never_none(self) -> None:
prop = SimpleNamespace(
type="pointer",
fixed_type=SimpleNamespace(identifier="Scene"),
is_never_none=True,
)
self.assertEqual(rna_property_to_type(prop), "Scene")
def test_pointer_defaults_to_nullable_without_attr(self) -> None:
prop = SimpleNamespace(
type="pointer",
fixed_type=SimpleNamespace(identifier="Object"),
)
self.assertEqual(rna_property_to_type(prop), "Object | None")
def test_pointer_function_return_stays_non_nullable(self) -> None:
# Function returns get nullable_pointer=False because Blender raises
# on failure rather than returning None, even though is_never_none=False.
prop = SimpleNamespace(
type="pointer",
fixed_type=SimpleNamespace(identifier="Object"),
is_never_none=False,
)
self.assertEqual(rna_property_to_type(prop, nullable_pointer=False), "Object")
def test_pointer_function_return_never_none_stays_non_nullable(self) -> None:
prop = SimpleNamespace(
type="pointer",
fixed_type=SimpleNamespace(identifier="Scene"),
is_never_none=True,
)
self.assertEqual(rna_property_to_type(prop, nullable_pointer=False), "Scene")
class TestDescriptionHintsNullable(unittest.TestCase):
def test_may_be_none_phrase(self) -> None:
self.assertTrue(
description_hints_nullable(
"The current space, may be None in background-mode"
)
)
def test_can_be_none_phrase(self) -> None:
self.assertTrue(
description_hints_nullable(
"The active object — can be None when no object is selected"
)
)
def test_may_be_null_phrase(self) -> None:
self.assertTrue(description_hints_nullable("Result may be null on failure"))
def test_case_insensitive(self) -> None:
self.assertTrue(description_hints_nullable("This MAY BE NONE in some cases"))
def test_no_hint_returns_false(self) -> None:
self.assertFalse(description_hints_nullable("The active scene"))
def test_empty_returns_false(self) -> None:
self.assertFalse(description_hints_nullable(""))
if __name__ == "__main__":
unittest.main()