def test_non_required_subclass_survives_read_write(self): ItemModel = Schema.entity("item", None, None, { "name": Schema.prop(Schema.STRING), }) ItemModel1 = Schema.entity("item1", ItemModel, None, { "one": Schema.prop(Schema.STRING), }) ItemModel2 = Schema.entity("item2", ItemModel, None, { "two": Schema.prop(Schema.STRING), }) ListModel = Schema.entity( "list", None, None, { "items": Schema.array(Schema.component(ItemModel, False)), }) import pprint context = Schema.SimpleEntityContext() with contextlib.closing(ListModel.create(context)) as l: l._append_item("items", ItemModel1.create(None, { "name": "1", "one": "11" })) l._append_item("items", ItemModel2.create(None, { "name": "2", "two": "22" })) d = l.write() self.assertEqual("1", l._get_array_item("items", 0).name) self.assertEqual("11", l._get_array_item("items", 0).one) self.assertEqual("2", l._get_array_item("items", 1).name) self.assertEqual("22", l._get_array_item("items", 1).two) Schema.unregister_entity_type("item1") with contextlib.closing(ListModel.create(context)) as l: l.read(d) self.assertEqual(d, l.write()) self.assertIsNone(l._get_array_item("items", 0)) self.assertEqual("2", l._get_array_item("items", 1).name) self.assertEqual("22", l._get_array_item("items", 1).two) # re-register and make sure it loads Schema.register_entity_type("item1", ItemModel1) with contextlib.closing(ListModel.create(context)) as l: l.read(d) self.assertEqual(d, l.write()) self.assertEqual("1", l._get_array_item("items", 0).name) self.assertEqual("11", l._get_array_item("items", 0).one) self.assertEqual("2", l._get_array_item("items", 1).name) self.assertEqual("22", l._get_array_item("items", 1).two)
def test_setting_reference_before_context_works(self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) RefModel = Schema.entity("ref", None, None, {"item": Schema.reference(ItemModel)}) context = Schema.SimpleEntityContext() ref = RefModel.create() item = ItemModel.create() ref._set_field_value("item", item) self.assertEqual( item, ref._get_field_value("item")) # check that the field value was set self.assertIsNone(item._entity_context ) # setting the item should propagate the context ref._set_entity_context(context) self.assertEqual( item, ref._get_field_value("item")) # check that the field value was set self.assertIsNone( item._entity_context ) # setting a reference item should NOT propagate the context ref._set_entity_context(None) self.assertEqual( item, ref._get_field_value("item")) # check that the field value was set self.assertIsNone(item._entity_context ) # setting the item should propagate the context ref._set_field_value("item", None) self.assertIsNone(ref._get_field_value("item")) self.assertIsNone(item._entity_context) # context should be unset now
def test_reference_is_initially_none(self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) RefModel = Schema.entity("ref", None, None, {"item": Schema.reference(ItemModel)}) ref = RefModel.create(Schema.SimpleEntityContext()) self.assertIsNone(ref._get_field_value("item"))
def test_component_container_is_set_when_inserting_item_and_cleared_when_removing( self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) ContainerModel = Schema.entity( "c", None, None, { "c_items": Schema.array(Schema.component(ItemModel)), "r_items": Schema.array(Schema.reference(ItemModel)), "c_item": Schema.component(ItemModel), "r_item": Schema.reference(ItemModel), }) context = Schema.SimpleEntityContext() c = ContainerModel.create(context) c._append_item("c_items", ItemModel.create()) c._append_item("c_items", ItemModel.create()) c._append_item("r_items", c._get_array_item("c_items", 0)) c._append_item("r_items", c._get_array_item("c_items", 1)) c._set_field_value("c_item", ItemModel.create()) c._set_field_value("r_item", c.c_item) self.assertEqual(c, c._get_array_item("c_items", 0)._container) self.assertEqual(c, c._get_array_item("c_items", 1)._container) self.assertEqual(c, c._get_array_item("r_items", 0)._container) self.assertEqual(c, c._get_array_item("r_items", 1)._container) self.assertEqual(c, c._get_field_value("c_item")._container) self.assertEqual(c, c._get_field_value("r_item")._container) c_item0 = c._get_array_item("c_items", 0) c._remove_item("c_items", c_item0) self.assertIsNone(c_item0._container) c_item = c._get_field_value("c_item") c._set_field_value("c_item", None) self.assertIsNone(c_item._container)
def test_new_entity_has_uuid_and_dates(self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) item = ItemModel.create() self.assertIsNotNone(item.uuid) self.assertIsNotNone(item.modified) d = item.write_to_dict() self.assertIn("uuid", d) self.assertIn("modified", d)
def test_entity_updates_modified_and_parent_when_property_changes(self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) item = ItemModel.create() self.assertIsNotNone(item.uuid) self.assertIsNotNone(item.modified) d = item.write_to_dict() self.assertIn("uuid", d) self.assertIn("modified", d) m = item.modified item._set_field_value("flag", False) item._set_field_value("flag", True) self.assertLess(m, item.modified)
def test_changing_entity_field_updates_data_structure(self): TestModel = Schema.entity("test_model", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) with TestContext.create_memory_context() as test_context: DataStructure.DataStructure.register_entity(TestModel) try: document_model = test_context.create_document_model() data_structure = DataStructure.DataStructure(structure_type="test_model") document_model.append_data_structure(data_structure) self.assertIsNotNone(data_structure.entity) data_structure.entity.flag = False self.assertEqual(data_structure.flag, False) self.assertEqual(data_structure.flag, data_structure.entity.flag) data_structure.entity.flag = True self.assertEqual(data_structure.flag, True) self.assertEqual(data_structure.flag, data_structure.entity.flag) finally: DataStructure.DataStructure.unregister_entity(TestModel)
def test_setting_reference_triggers_property_changes_event(self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) RefModel = Schema.entity("ref", None, None, {"item": Schema.reference(ItemModel)}) context = Schema.SimpleEntityContext() ref = RefModel.create(context) item = ItemModel.create() changed = False def property_changed(name: str) -> None: nonlocal changed changed = True with contextlib.closing( ref.property_changed_event.listen( property_changed)) as listener: ref._set_field_value("item", item) self.assertTrue(changed)
def test_inserting_and_removing_array_components_and_references_trigger_events( self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) ContainerModel = Schema.entity( "c", None, None, { "c_items": Schema.array(Schema.component(ItemModel)), "r_items": Schema.array(Schema.reference(ItemModel)), }) context = Schema.SimpleEntityContext() c = ContainerModel.create(context) inserted_count = 0 removed_count = 0 def item_inserted(key: str, value, index: int) -> None: nonlocal inserted_count inserted_count += 1 def item_removed(key: str, value, index: int) -> None: nonlocal removed_count removed_count += 1 with contextlib.closing(c.item_inserted_event.listen(item_inserted)): with contextlib.closing(c.item_removed_event.listen(item_removed)): # test components c._append_item("c_items", ItemModel.create()) c._append_item("c_items", ItemModel.create()) self.assertEqual(2, inserted_count) self.assertEqual(0, removed_count) c._remove_item("c_items", c._get_array_item("c_items", 0)) self.assertEqual(2, inserted_count) self.assertEqual(1, removed_count) # test references c._append_item("r_items", ItemModel.create()) c._append_item("r_items", ItemModel.create()) self.assertEqual(4, inserted_count) self.assertEqual(1, removed_count) c._remove_item("r_items", c._get_array_item("r_items", 0)) self.assertEqual(4, inserted_count) self.assertEqual(2, removed_count)
def test_inserting_and_removing_array_components_and_references_updates_contexts( self): ItemModel = Schema.entity("item", None, None, {"flag": Schema.prop(Schema.BOOLEAN)}) ContainerModel = Schema.entity( "c", None, None, { "c_items": Schema.array(Schema.component(ItemModel)), "r_items": Schema.array(Schema.reference(ItemModel)), }) context = Schema.SimpleEntityContext() c = ContainerModel.create(context) # test component c_item = ItemModel.create() c._append_item("c_items", c_item) self.assertIsNotNone(c_item._entity_context) c._remove_item("c_items", c_item) self.assertIsNone(c_item._entity_context) # test reference c._append_item("r_items", c_item) r_item = c._get_array_item("r_items", 0) self.assertIsNone(r_item._entity_context ) # setting a reference should NOT propagate context c._remove_item("r_items", c_item) self.assertIsNone(r_item._entity_context)
specifier = project.create_specifier(object, allow_partial=allow_partial) if project else None specifier_uuid = specifier.item_uuid if specifier else object.uuid d = {"version": 1, "type": "graphic", "uuid": str(specifier_uuid)} if specifier and specifier.context_uuid: d["context_uuid"] = str(specifier.context_uuid) return d elif isinstance(object, DataStructure): project = project or object.project specifier = project.create_specifier(object, allow_partial=allow_partial) if project else None specifier_uuid = specifier.item_uuid if specifier else object.uuid d = {"version": 1, "type": "structure", "uuid": str(specifier_uuid)} if specifier and specifier.context_uuid: d["context_uuid"] = str(specifier.context_uuid) return d elif isinstance(object, DisplayItem.DisplayItem): project = project or object.project specifier = project.create_specifier(object, allow_partial=allow_partial) if project else None specifier_uuid = specifier.item_uuid if specifier else object.uuid d = {"version": 1, "type": "display_item", "uuid": str(specifier_uuid)} if specifier and specifier.context_uuid: d["context_uuid"] = str(specifier.context_uuid) return d return None ElementalMappingEdge = Schema.entity("elemental_mapping_edge", None, None, { "atomic_number": Schema.prop(Schema.INT), "shell_number": Schema.prop(Schema.INT), "subshell_index": Schema.prop(Schema.INT), "fit_interval": Schema.fixed_tuple([Schema.prop(Schema.FLOAT), Schema.prop(Schema.FLOAT)]), "signal_interval": Schema.fixed_tuple([Schema.prop(Schema.FLOAT), Schema.prop(Schema.FLOAT)]), }) DataStructure.register_entity(ElementalMappingEdge, entity_name="Elemental Mapping Edge")
def test_deepcopy(self): RecordModel = Schema.record({ "value": Schema.prop(Schema.INT), }) ItemModel = Schema.entity("item", None, None, { "name": Schema.prop(Schema.STRING), "record": RecordModel, }) ListModel = Schema.entity( "list", None, None, { "c_items": Schema.array(Schema.component(ItemModel)), "r_items": Schema.array(Schema.reference(ItemModel)), }) context = Schema.SimpleEntityContext() with contextlib.closing(ListModel.create(context)) as l: l._append_item( "c_items", ItemModel.create(None, { "name": "aa", "record": { "value": 4 } })) l._append_item( "c_items", ItemModel.create(None, { "name": "bb", "record": { "value": 5 } })) l._append_item("r_items", l._get_array_item("c_items", 0)) l._append_item("r_items", l._get_array_item("c_items", 1)) self.assertEqual(4, l._get_array_item("c_items", 0).record.value) self.assertEqual(5, l._get_array_item("c_items", 1).record.value) self.assertEqual(l._get_array_item("r_items", 0), l._get_array_item("c_items", 0)) self.assertEqual(l._get_array_item("r_items", 1), l._get_array_item("c_items", 1)) with contextlib.closing(copy.deepcopy(l)) as ll: self.assertEqual( l._get_array_item("c_items", 0).uuid, ll._get_array_item("c_items", 0).uuid) self.assertEqual( l._get_array_item("c_items", 1).uuid, ll._get_array_item("c_items", 1).uuid) self.assertEqual( l._get_array_item("c_items", 0).modified, ll._get_array_item("c_items", 0).modified) self.assertEqual( l._get_array_item("c_items", 1).modified, ll._get_array_item("c_items", 1).modified) self.assertEqual( l._get_array_item("c_items", 0).name, ll._get_array_item("c_items", 0).name) self.assertEqual( l._get_array_item("c_items", 1).name, ll._get_array_item("c_items", 1).name) self.assertEqual(4, ll._get_array_item("c_items", 0).record.value) self.assertEqual(5, ll._get_array_item("c_items", 1).record.value) self.assertEqual(ll._get_array_item("r_items", 0), ll._get_array_item("c_items", 0)) self.assertEqual(ll._get_array_item("r_items", 1), ll._get_array_item("c_items", 1))
# TODO: support external data concept with loaded/unloaded property # TODO: support loaded/unloaded entities? # TODO: support mounted/unmounted entity concept (projects) # TODO: support write delay / transactions # TODO: access to auto proxy items for references # TODO: closing, reading, inserting, removing, modifying, copying, container # TODO: notifying, storage, resolving, moving # TODO: are interval descriptors implicit now? # TODO: display_layers could be a record # TODO: display_properties could be a record # TODO: layout could be a record # TODO: closed_items should be a set of references Calibration = Schema.record({ "offset": Schema.prop(Schema.FLOAT), "scale": Schema.prop(Schema.FLOAT), "units": Schema.prop(Schema.STRING), }) Point = Schema.fixed_tuple( [Schema.prop(Schema.FLOAT), Schema.prop(Schema.FLOAT)]) Size = Schema.fixed_tuple( [Schema.prop(Schema.FLOAT), Schema.prop(Schema.FLOAT)]) Rect = Schema.fixed_tuple([Point, Size]) Vector = Schema.fixed_tuple([Point, Point])