more test cases
This commit is contained in:
@@ -2481,6 +2481,99 @@ class MainTests(unittest.TestCase):
|
||||
self.assertFalse(hasattr(b2.F1, "xb"))
|
||||
self.assertFalse(hasattr(c2.F1, "xc"))
|
||||
|
||||
def test_dict_field_override_with_nested_containers(self):
|
||||
class App(dm.BaseAppliance):
|
||||
data: dict[str, list[int]] = {"numbers": [1, 2]}
|
||||
|
||||
app = App(data={"numbers": [9, 8]})
|
||||
# Dict must be frozen, lists inside must become tuples
|
||||
self.assertEqual(type(app.data).__name__, "frozendict")
|
||||
self.assertIsInstance(app.data["numbers"], tuple)
|
||||
self.assertEqual(app.data["numbers"], (9, 8))
|
||||
|
||||
# Wrong type inside list should raise
|
||||
with self.assertRaises(dm.InvalidFieldValue):
|
||||
App(data={"numbers": [1, "oops"]})
|
||||
|
||||
def test_feature_dict_override_with_nested_containers(self):
|
||||
class App(dm.BaseAppliance):
|
||||
class F1(dm.BaseFeature):
|
||||
values: list[int] = [1, 2]
|
||||
|
||||
app = App(F1={"values": [5, 6]})
|
||||
self.assertEqual(app.F1.values, (5, 6)) # deepfreeze → tuple
|
||||
|
||||
# Invalid type in list should fail
|
||||
with self.assertRaises(dm.InvalidFieldValue):
|
||||
App(F1={"values": [1, "oops"]})
|
||||
|
||||
def test_initializer_modifies_nested_containers(self):
|
||||
class App(dm.BaseAppliance):
|
||||
data: dict[str, list[int]] = {"nums": [1]}
|
||||
|
||||
@classmethod
|
||||
def __initializer(cls):
|
||||
# Append into nested list
|
||||
cls.data["nums"].append(2)
|
||||
|
||||
app = App()
|
||||
self.assertEqual(app.data["nums"], (1, 2)) # frozen tuple after init
|
||||
|
||||
def test_feature_dict_override_with_unknown_key(self):
|
||||
class App(dm.BaseAppliance):
|
||||
class F1(dm.BaseFeature):
|
||||
a: int = 1
|
||||
|
||||
# Dict override with unknown field 'zzz'
|
||||
with self.assertRaises(dm.InvalidFieldValue):
|
||||
App(F1={"zzz": 42})
|
||||
|
||||
def test_schema_isolation_across_multiple_feature_overrides(self):
|
||||
class App(dm.BaseAppliance):
|
||||
class F1(dm.BaseFeature):
|
||||
a: int = 1
|
||||
|
||||
class F1a(App.F1):
|
||||
a = 10
|
||||
|
||||
class F1b(App.F1):
|
||||
a = 20
|
||||
|
||||
app1 = App(F1=F1a)
|
||||
self.assertIsInstance(app1.F1, F1a)
|
||||
self.assertEqual(app1.F1.a, 10)
|
||||
|
||||
app2 = App(F1=F1b)
|
||||
self.assertIsInstance(app2.F1, F1b)
|
||||
self.assertEqual(app2.F1.a, 20)
|
||||
|
||||
# Original appliance schema must not be polluted
|
||||
app3 = App()
|
||||
self.assertIsInstance(app3.F1, App.F1)
|
||||
self.assertEqual(app3.F1.a, 1)
|
||||
|
||||
def test_feature_inheritance_with_annotated_fields(self):
|
||||
from typing_extensions import Annotated
|
||||
|
||||
class App(dm.BaseAppliance):
|
||||
class F1(dm.BaseFeature):
|
||||
a: Annotated[int, dm.DABFieldInfo(doc="field a")] = 1
|
||||
|
||||
# ✅ Subclass override must inherit from parent F1
|
||||
class F1Ex(App.F1):
|
||||
b: str = "ok"
|
||||
|
||||
app = App(F1=F1Ex)
|
||||
self.assertIsInstance(app.F1, F1Ex)
|
||||
self.assertEqual((app.F1.a, app.F1.b), (1, "ok"))
|
||||
|
||||
# ❌ Wrong: fresh BaseFeature under same name
|
||||
with self.assertRaises(dm.InvalidFeatureInheritance):
|
||||
|
||||
class Bad(App):
|
||||
class F1(dm.BaseFeature):
|
||||
fail: str = "oops"
|
||||
|
||||
|
||||
# ---------- main ----------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user