def test_update_member_with_link(self): my_entity = create_entity() new_parent = MyEntityParent() new_parent.text = self.UPDATED_TEXT new_parent.id = 2 my_entity.parent = new_parent coll = create_staging_collection(IMyEntity) member = coll.create_member(my_entity) mp = self._make_mapping() attribute_options = { ('parent', ): { WRITE_AS_LINK_OPTION: True }, ('nested_parent', ): { IGNORE_OPTION: True } } mp_cloned = mp.clone(attribute_options=attribute_options) data_el = mp_cloned.map_to_data_element(member) # The linked-to parent needs to be in the root collection. my_entity.parent = None del member del my_entity parent_coll = get_root_collection(IMyEntityParent) parent_coll.create_member(new_parent) my_entity = create_entity() coll = get_root_collection(IMyEntity) context = coll.create_member(my_entity) self.assert_equal(context.parent.text, MyEntity.DEFAULT_TEXT) context.update_from_data(data_el) self.assert_equal(context.parent.text, self.UPDATED_TEXT)
def test_update_member_with_link(self): my_entity = create_entity() new_parent = MyEntityParent() new_parent.text = self.UPDATED_TEXT new_parent.id = 2 my_entity.parent = new_parent coll = create_staging_collection(IMyEntity) member = coll.create_member(my_entity) mp = self._make_mapping() attribute_options = {('parent',):{WRITE_AS_LINK_OPTION:True}, ('nested_parent',):{IGNORE_OPTION:True}} mp_cloned = mp.clone(attribute_options=attribute_options) data_el = mp_cloned.map_to_data_element(member) # The linked-to parent needs to be in the root collection. my_entity.parent = None del member del my_entity parent_coll = get_root_collection(IMyEntityParent) parent_coll.create_member(new_parent) my_entity = create_entity() coll = get_root_collection(IMyEntity) context = coll.create_member(my_entity) self.assert_equal(context.parent.text, MyEntity.DEFAULT_TEXT) context.update_from_data(data_el) self.assert_equal(context.parent.text, self.UPDATED_TEXT)
def test_delete_cascade(self, class_entity_repo, monkeypatch): new_parent1 = MyEntityParent() new_ent1 = MyEntity() new_ent1.parent = new_parent1 new_child1 = MyEntityChild() new_child1.parent = new_ent1 child_rel_agg = self._make_rel_agg(class_entity_repo, new_ent1) child_rel_agg.add(new_child1) new_parent1.id = 1 new_ent1.id = 1 new_child1.id = 1 agg = class_entity_repo.get_aggregate(IMyEntity) child_agg = class_entity_repo.get_aggregate(IMyEntityChild) assert len(list(child_agg.iterator())) == 1 assert len(list(agg.iterator())) == 1 assert new_ent1.children == [new_child1] assert new_child1.parent == new_ent1 csc = DEFAULT_CASCADE | RELATION_OPERATIONS.REMOVE children_attr = get_domain_class_attribute(MyEntity, 'children') parent_attr = get_domain_class_attribute(MyEntityChild, 'parent') monkeypatch.setattr(children_attr, 'cascade', csc) monkeypatch.setattr(parent_attr, 'cascade', csc) child_rel_agg.remove(new_child1) assert new_ent1.children == [] assert new_child1.parent is None assert len(list(child_agg.iterator())) == 0 if self.__class__.__name__.startswith('TestMemory'): # FIXME: Transparent modification of RDB mapper cascades # does not work yet. assert len(list(agg.iterator())) == 0 assert len(list(child_rel_agg.iterator())) == 0
def _make_test_entity_member(): parent = MyEntityParent(id=0) entity = MyEntity(id=0, parent=parent) parent.child = entity child = MyEntityChild(id=0, parent=entity) entity.children.append(child) grandchild = MyEntityGrandchild(id=0, parent=child) child.children.append(grandchild) coll = create_staging_collection(IMyEntity) return coll.create_member(entity)
def _make_child(self, child_agg, child_id=0): new_parent = MyEntityParent() new_ent = MyEntity() new_ent.parent = new_parent new_child = MyEntityChild() new_ent.children.append(new_child) if new_child.parent is None: new_child.parent = new_ent child_agg.add(new_child) new_parent.id = child_id new_ent.id = child_id new_child.id = child_id return new_child
def test_basics(self, class_entity_repo): agg = class_entity_repo.get_aggregate(IMyEntity) child_agg = class_entity_repo.get_aggregate(IMyEntityChild) new_child0 = self._make_child(child_agg) new_parent1 = MyEntityParent() new_ent1 = MyEntity() new_ent1.parent = new_parent1 new_child1 = MyEntityChild() child_rel_agg = self._make_rel_agg(class_entity_repo, new_ent1) assert len(list(child_agg.iterator())) == 1 assert len(list(agg.iterator())) == 1 assert len(list(child_rel_agg.iterator())) == 0 # Adding to a relationship aggregate ..... child_rel_agg.add(new_child1) # ....... adds to root aggregates: assert len(list(child_agg.iterator())) == 2 # ....... adds (along the cascade) to parent root aggregate: assert len(list(agg.iterator())) == 2 # ....... appends to children: assert new_ent1.children == [new_child1] # get by ID and slug, filtering. assert child_rel_agg.get_by_id(new_child1.id).id == new_child1.id assert \ child_rel_agg.get_by_slug(new_child1.slug).slug == new_child1.slug child_rel_agg.filter = eq(id=2) assert child_rel_agg.get_by_id(new_child1.id) is None assert child_rel_agg.get_by_slug(new_child1.slug) is None # update. upd_child0 = MyEntityChild(id=0) txt = 'FROBNIC' upd_child0.text = txt child_rel_agg.update(upd_child0) assert new_child0.text == txt
def test_alias(self): ent = MyEntityParent() mb = MyEntityParentMember.create_from_entity(ent) alias_descr = getattr(MyEntityParentMember, 'text_alias') self.assert_true(isinstance(alias_descr, attribute_alias)) self.assert_equal(mb.text_alias, mb.text) mb.text_alias = 'altered text' self.assert_equal(mb.text, mb.text_alias)
def test_add_one_to_one(self, class_entity_repo): new_parent1 = MyEntityParent(id=1) new_ent1 = MyEntity(id=1) parent_rel_agg = self._make_rel_agg(class_entity_repo, new_ent1, 'parent') assert new_ent1.parent is None parent_rel_agg.add(new_parent1) assert new_ent1.parent == new_parent1
def test_update_member(self): my_entity = create_entity() new_parent = MyEntityParent() new_parent.text = self.UPDATED_TEXT new_parent.id = 2 my_entity.parent = new_parent coll = create_staging_collection(IMyEntity) member = coll.create_member(my_entity) mp = self._make_mapping() data_el = mp.map_to_data_element(member) del member del my_entity my_entity = create_entity() coll = get_root_collection(IMyEntity) context = coll.create_member(my_entity) self.assert_equal(context.parent.text, MyEntity.DEFAULT_TEXT) context.update_from_data(data_el) self.assert_equal(context.parent.text, self.UPDATED_TEXT)
def test_collection_access(self): parent = MyEntityParent(id=0) entity = MyEntity(id=0, parent=parent) coll = get_root_collection(IMyEntity) member = coll.create_member(entity) self.assert_true(isinstance(member.children, Collection)) child_entity = MyEntityChild() member.children.create_member(child_entity) self.assert_equal(len(member.children), 1)
def create_entity(entity_id=0, entity_text=None): my_entity = MyEntity(text=entity_text) my_entity.id = entity_id my_entity_parent = MyEntityParent() my_entity_parent.id = entity_id my_entity.parent = my_entity_parent my_entity_child = MyEntityChild() my_entity_child.id = entity_id my_entity.children.append(my_entity_child) my_entity_grandchild = MyEntityGrandchild() my_entity_grandchild.id = entity_id my_entity_child.children.append(my_entity_grandchild) # If we run with the SQLAlchemy backend, the back references are populated # automatically. if my_entity_child.parent is None: my_entity_child.parent = my_entity if my_entity_grandchild.parent is None: my_entity_grandchild.parent = my_entity_child return my_entity
def _make_test_entity_member(): parent = MyEntityParent() entity = MyEntity(parent=parent) if parent.child is None: parent.child = entity child = MyEntityChild() entity.children.append(child) if child.parent is None: child.parent = entity grandchild = MyEntityGrandchild() child.children.append(grandchild) if grandchild.parent is None: grandchild.parent = child coll = create_staging_collection(IMyEntity) mb = coll.create_member(entity) parent.id = 0 entity.id = 0 child.id = 0 grandchild.id = 0 return mb
def test_entity_attr(self): attr = get_domain_class_attribute(IMyEntity, 'parent') my_parent = MyEntityParent(id=0) self._run_test(attr, my_parent, 'child', ValueEqualToFilterSpecification, ValueEqualToFilterSpecification, 0) attr = get_domain_class_attribute(IMyEntityChild, 'parent') my_child = MyEntityChild(id=1) self._run_test(attr, my_child, 'children', ValueContainsFilterSpecification, ValueEqualToFilterSpecification, 1)
def test_set_member(self): my_entity = create_entity() coll = get_root_collection(IMyEntity) mb = coll.create_member(my_entity) txt = 'FROBNIC' new_parent = MyEntityParent(text=txt) parent_coll = get_root_collection(IMyEntityParent) parent_mb = parent_coll.create_member(new_parent) self.assert_not_equal(mb.parent.text, txt) mb.parent = parent_mb self.assert_equal(mb.parent.text, txt)
def test_add_with_data_element(self): my_entity = MyEntity() my_entity_parent = MyEntityParent() my_entity.parent = my_entity_parent coll = create_staging_collection(IMyEntity) member = coll.create_member(my_entity) mp = self._make_mapping() data_el = mp.map_to_data_element(member) del member root_coll = get_root_collection(IMyEntity) root_coll.add(data_el) self.assert_equal(len(coll), 1)
def create_entity(entity_id=0, entity_text=None): my_entity = MyEntity(text=entity_text) my_entity.id = entity_id my_entity_parent = MyEntityParent() my_entity_parent.id = entity_id my_entity.parent = my_entity_parent my_entity_child = MyEntityChild() my_entity_child.id = entity_id my_entity_child.parent = my_entity if len(my_entity.children) == 0: # Tests that use the ORM will not need to go here. my_entity.children.append(my_entity_child) assert len(my_entity.children) == 1 my_entity_grandchild = MyEntityGrandchild() my_entity_grandchild.id = entity_id my_entity_grandchild.parent = my_entity_child # Tests that use the ORM will not need this. if len(my_entity.children) == 0: my_entity.children.append(my_entity_child) if len(my_entity_child.children) == 0: my_entity_child.children.append(my_entity_grandchild) return my_entity
def test_collection_access(self): parent = MyEntityParent() entity = MyEntity(parent=parent) coll = get_root_collection(IMyEntity) member = coll.create_member(entity) self.assert_true(isinstance(member.children, Collection)) i = 0 n = 5 while i < n: child_entity = MyEntityChild() member.children.create_member(child_entity) i += 1 self.assert_equal(len(member.children), n)
def test_nested(self, class_entity_repo): session = class_entity_repo.session_factory() ent = MyEntity() parent = MyEntityParent() ent.parent = parent child = MyEntityChild() ent.children.append(child) session.add(MyEntity, ent) session.commit() assert len(session.query(MyEntityChild).all()) == 1 assert len(session.query(MyEntityParent).all()) == 1 fetched_ent = session.query(MyEntity).one() assert not fetched_ent.parent is None assert len(fetched_ent.children) == 1
def test_update_nested_member_from_data(self, resource_repo): # Set up member that does not have a parent. coll = resource_repo.get_collection(IMyEntity) ent = MyEntity(id=1) mb = coll.create_member(ent) # Set up second member with same ID that does have a parent. tmp_coll = create_staging_collection(IMyEntity) parent = MyEntityParent(id=0) upd_ent = MyEntity(id=1, parent=parent) upd_mb = tmp_coll.create_member(upd_ent) rpr = as_representer(mb, CsvMime) attribute_options = {('parent', ): {WRITE_AS_LINK_OPTION: False}} with rpr.with_updated_configuration( attribute_options=attribute_options): de = rpr.resource_to_data(upd_mb) mb.update(de) assert mb.parent.id == parent.id
def create_entity(entity_id=0, entity_text=None): my_entity_parent = MyEntityParent(id=entity_id, text=entity_text) my_entity_grandchild = MyEntityGrandchild(id=entity_id, text=entity_text) my_entity_child = MyEntityChild(id=entity_id, text=entity_text, children=[my_entity_grandchild]) my_entity = MyEntity(id=entity_id, text=entity_text, parent=my_entity_parent, children=[my_entity_child]) # If we run with the SQLAlchemy backend, the back references are populated # automatically. if my_entity_child.parent is None: my_entity_child.parent = my_entity if my_entity_grandchild.parent is None: my_entity_grandchild.parent = my_entity_child return my_entity
def test_update_nested_member_from_data(self): # Set up member that does not have a parent. ent = MyEntity(id=1) mb = MyEntityMember.create_from_entity(ent) # Set up second member with same ID that does have a parent. parent = MyEntityParent(id=0) upd_ent = MyEntity(id=1, parent=parent) upd_mb = MyEntityMember.create_from_entity(upd_ent) rpr = as_representer(mb, CsvMime) attribute_options = { ('parent', ): { WRITE_AS_LINK_OPTION: False }, } rpr.configure(attribute_options=attribute_options) de = rpr.data_from_resource(upd_mb) mb.update_from_data(de) self.assert_equal(mb.parent.id, parent.id)
def test_make_relationship(self): ent = MyEntity(id=0) coll = get_root_collection(IMyEntity) mb = coll.create_member(ent) attr = get_resource_class_attribute(IMyEntity, 'parent') rel = attr.make_relationship(mb) self.assert_true(isinstance(rel, ResourceRelationship)) parent = MyEntityParent(id=0) parent_coll = get_root_collection(IMyEntityParent) parent_mb = parent_coll.create_member(parent) self.assert_true(ent.parent is None) rel.add(parent_mb) self.assert_true(ent.parent is parent) rel.remove(parent_mb) self.assert_true(ent.parent is None) rel = attr.make_relationship(ent) self.assert_true(isinstance(rel, DomainRelationship)) self.assert_raises(ValueError, attr.make_relationship, None)
def test_state_data(self): data = dict(text='FOO', number=-1, parent=MyEntityParent(), children=[MyEntityChild()]) entity = MyEntity(**data) # We don't want to test the required unit of work here. uow = MagicMock() self.assert_raises(ValueError, EntityState.get_state, entity) entity.__everest__ = EntityState(entity, uow) state_data = EntityState.get_state(entity).data for attr, value in state_data.items(): if attr.resource_attr == 'number': number_attr = attr elif attr.resource_attr == 'parent': parent_attr = attr elif attr.resource_attr == 'parent_text': parent_text_attr = attr if attr.resource_attr in data: self.assert_equal(value, data[attr.resource_attr]) new_number = -2 state_data[number_attr] = new_number EntityState.get_state(entity).data = state_data self.assert_equal(entity.number, new_number) new_entity = MyEntity() self.assert_not_equal(new_entity.number, new_number) new_entity.__everest__ = EntityState(new_entity, uow) EntityState.transfer_state_data(entity, new_entity) self.assert_equal(new_entity.number, new_number) # Make setting invalid attribute fail. invalid_number_attr = terminal_attribute(str, 'grmbl') del state_data[number_attr] state_data[invalid_number_attr] = -2 with self.assert_raises(ValueError) as cm: EntityState.get_state(entity).data = state_data self.assert_true(cm.exception.args[0].startswith('Can not set')) # Make set nested attribute fail. entity.parent = None del state_data[invalid_number_attr] del state_data[parent_attr] state_data[parent_text_attr] = 'FOO PARENT' state = EntityState.get_state(entity) self.assert_raises(AttributeError, setattr, state, 'data', state_data)
def create_entity_tree(id=0, text=None): # pylint: disable=W0622 my_entity_grandchild = MyEntityGrandchild(id=id, text=text) my_entity_child = MyEntityChild(id=id, text=text, children=[my_entity_grandchild]) my_entity_parent = MyEntityParent( id=id, text=text, ) my_entity = MyEntity(id=id, text=text, children=[my_entity_child], parent=my_entity_parent) # If we run with the SQLAlchemy backend, the back references are populated # automatically. if my_entity_child.parent is None: my_entity_child.parent = my_entity if my_entity_grandchild.parent is None: my_entity_grandchild.parent = my_entity_child return my_entity
def test_member_access(self): parent = MyEntityParent() entity = MyEntity(parent=parent) member = MyEntityMember.create_from_entity(entity) self.assert_true(isinstance(member.parent, MyEntityParentMember)) self.assert_true(member.parent.get_entity() is parent)