def test_append(): p = MockProperty() o = object() c = collection(p, o, str) c.append("s") assert p.values == [(o, "s")]
def test_swap(): o = MockElement() c = collection(None, o, int) c.items = ["a", "b", "c"] c.swap("a", "c") assert c.items == ["c", "b", "a"] assert o.events
def test_count(): c = collection(None, None, int) c.items = [1, 2, 2] assert c.count(1) == 1 assert c.count(2) == 2 assert c.count(3) == 0
def _set(self, obj, value, from_opposite=False, do_notify=True): """ Set a new value for our attribute. If this is a collection, append to the existing collection. This method is called from the opposite association property. """ if not (isinstance(value, self.type) or (value is None and self.upper == 1)): raise AttributeError(f"Value should be of type {self.type.__name__}") # Remove old value only for uni-directional associations if self.upper == 1: old = self._get(obj) # do nothing if we are assigned our current value: # Still do your thing, since undo handlers expect that. if value is old: return if old: self._del(obj, old, from_opposite=from_opposite, do_notify=False) if do_notify: event: AssociationChangeEvent = AssociationSetEvent( obj, self, old, value ) if value is None: if do_notify: self.handle(event) return setattr(obj, self._name, value) else: # Set the actual value c = self._get(obj) if not c: c = collection(self, obj, self.type) setattr(obj, self._name, c) elif value in c: return c.items.append(value) if do_notify: event = AssociationAddEvent(obj, self, value) if not from_opposite and self.opposite: opposite = getattr(type(value), self.opposite) if not opposite.opposite: opposite.stub = self opposite._set(value, obj, from_opposite=True, do_notify=do_notify) elif not self.opposite: if not self.stub: self.stub = associationstub(self) setattr(self.type, "UML_associationstub_%x" % id(self), self.stub) self.stub._set(value, obj) if do_notify: self.handle(event)
def _get_many(self, obj) -> collection[T]: v: Optional[collection[T]] = getattr(obj, self._name, None) if v is None: # Create the empty collection here since it might # be used to add. v = collection(self, obj, self.type) setattr(obj, self._name, v) return v
def _set(self, obj, value, from_opposite=False, do_notify=True): """ Set a new value for our attribute. If this is a collection, append to the existing collection. This method is called from the opposite association property. """ if not (isinstance(value, self.type) or (value is None and self.upper == 1)): raise AttributeError("Value should be of type %s" % self.type.__name__) # Remove old value only for uni-directional associations if self.upper == 1: old = self._get(obj) # do nothing if we are assigned our current value: # Still do your thing, since undo handlers expect that. if value is old: return if old: self._del(obj, old, from_opposite=from_opposite, do_notify=False) if do_notify: event = AssociationSetEvent(obj, self, old, value) if value is None: if do_notify: self.handle(event) return setattr(obj, self._name, value) else: # Set the actual value c = self._get(obj) if not c: c = collection(self, obj, self.type) setattr(obj, self._name, c) elif value in c: return c.items.append(value) if do_notify: event = AssociationAddEvent(obj, self, value) if not from_opposite and self.opposite: opposite = getattr(type(value), self.opposite) if not opposite.opposite: opposite.stub = self opposite._set(value, obj, from_opposite=True, do_notify=do_notify) elif not self.opposite: if not self.stub: self.stub = associationstub(self) setattr(self.type, "UML_associationstub_%x" % id(self), self.stub) self.stub._set(value, obj) if do_notify: self.handle(event)
def _get(self, obj): # TODO: Handle lower and add items if lower > 0 try: return getattr(obj, self._name) except AttributeError: if self.upper == 1: return None else: # Create the empty collection here since it might be used to # add c = collection(self, obj, self.type) setattr(obj, self._name, c) return c
def _get(self, obj): # TODO: Handle lower and add items if lower > 0 try: return getattr(obj, self._name) except AttributeError: if self.upper == 1: return None else: # Create the empty collection here since it might be used to # add c = collection(self, obj, self.type) setattr(obj, self._name, c) return c
def _set_many(self, obj, value, from_opposite, do_notify) -> None: if not isinstance(value, self.type): raise AttributeError( f"Value should be of type {self.type.__name__}") # Set the actual value c: collection = self._get_many(obj) if not c: c = collection(self, obj, self.type) setattr(obj, self._name, c) elif value in c: return c.items.append(value) self._set_opposite(obj, value, from_opposite, do_notify) if do_notify: self.handle(AssociationAdded(obj, self, value))
def test_collect(): c = collection(None, None, int) c.items = [1, 2, 3] assert c.collect(lambda e: e * e) == [1, 4, 9]
def test_append_wrong_type(): c = collection(None, None, int) with pytest.raises(TypeError): c.append("s")
def test_not_empty(): c = collection(None, None, int) c.items = [1, 2, 3] assert not c.isEmpty()
def test_size(): c = collection(None, None, int) c.items = [1, 2] assert c.size() == 2
def test_excludes(): c = collection(None, None, int) c.items = [1, 2] assert not c.excludes(1) assert c.excludes(3)
def test_empty(): c = collection(None, None, int) assert c.isEmpty()
def test_select(): c = collection(None, None, int) c.items = [1, 2] assert c.select(lambda e: e > 1) == [2]
def test_excludesAll(): c = collection(None, None, int) c.items = [1, 2] assert not c.excludesAll([1]) assert c.excludesAll([3])