[PyObjC-svn] r2499 - in trunk/pyobjc/pyobjc-core: Lib/objc PyObjCTest
[email protected] Tue, 29 Jun 2010 08:45:49 -0500
| Newsgroups | gmane.comp.python.pyobjc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: ronaldoussoren
Date: Tue Jun 29 08:45:48 2010
New Revision: 2499
Log:
Implement tests for the various property types
and fix issues uncovered by those tests.
As noted before objc.set_property, objc.array_property
and objc.dict_property are still fairly minimal in that
they don't provide hooks for overriding methods.
Modified:
trunk/pyobjc/pyobjc-core/Lib/objc/_properties.py
trunk/pyobjc/pyobjc-core/PyObjCTest/loader.py
trunk/pyobjc/pyobjc-core/PyObjCTest/test_array_property.py
trunk/pyobjc/pyobjc-core/PyObjCTest/test_dict_property.py
trunk/pyobjc/pyobjc-core/PyObjCTest/test_object_property.py
trunk/pyobjc/pyobjc-core/PyObjCTest/test_set_property.py
Modified: trunk/pyobjc/pyobjc-core/Lib/objc/_properties.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/objc/_properties.py (original)
+++ trunk/pyobjc/pyobjc-core/Lib/objc/_properties.py Tue Jun 29 08:45:48 2010
@@ -279,14 +279,21 @@
class array_proxy (collections.MutableSequence):
# XXX: The implemenation should be complete, but is currently not
# tested.
- __slots__ = ('_name', '_wrapped', '_parent', '_ro')
+ __slots__ = ('_name', '_parent', '__wrapped', '_ro')
def __init__(self, name, parent, wrapped, read_only):
- self._wrapped = wrapped
self._name = name
self._parent = parent
self._ro = read_only
+ self.__wrapped = wrapped
+ @property
+ def _wrapped(self):
+ return self.__wrapped.__getvalue__(self._parent)
+
+ @_wrapped.setter
+ def _wrapped(self, value):
+ setattr(self._parent, self._name, value)
def __indexSetForIndex(self, index):
if isinstance(index, slice):
@@ -310,7 +317,7 @@
def __repr__(self):
- return '<array proxy for property ' + self._name + repr(self._wrapped) + '>'
+ return '<array proxy for property ' + self._name + ' ' + repr(self._wrapped) + '>'
def __reduce__(self):
# Ensure that the proxy itself doesn't get stored
@@ -620,9 +627,7 @@
def __set__(self, object, value):
if isinstance(value, array_property):
- print "set1", object, value
value = list(value)
- print "set2", object, value
super(array_property, self).__set__(object, value)
@@ -631,43 +636,129 @@
if v is None:
v = list()
object_property.__set__(self, object, v)
- return array_proxy(self._name, object, v, self._ro)
+ return array_proxy(self._name, object, self, self._ro)
-NSKeyValueUnionSetMutation = 1,
-NSKeyValueMinusSetMutation = 2,
-NSKeyValueIntersectSetMutation = 3,
+ def __getvalue__(self, object):
+ v = object_property.__get__(self, object, None)
+ if v is None:
+ v = list()
+ object_property.__set__(self, object, v)
+ return v
+
+
+NSKeyValueUnionSetMutation = 1
+NSKeyValueMinusSetMutation = 2
+NSKeyValueIntersectSetMutation = 3
NSKeyValueSetSetMutation = 4
-class set_proxy (object):
- __slots__ = ('_name', '_wrapped', '_parent', '_ro')
+class set_proxy (collections.MutableSet):
+ __slots__ = ('_name', '__wrapped', '_parent', '_ro')
+
+ def __init__(self, name, parent, wrapped, read_only):
+ self._name = name
+ self._parent = parent
+ self._ro = read_only
+ self.__wrapped = wrapped
+
+ def __repr__(self):
+ return '<set proxy for property ' + self._name + ' ' + repr(self._wrapped) + '>'
- def __init__(cls, name, parent, wrapped, read_only):
- v = cls.alloc().init()
- v._name = name
- v._wrapped = wrapped
- v._parent = parent
- v._ro = read_only
+ @property
+ def _wrapped(self):
+ return self.__wrapped.__getvalue__(self._parent)
+
+ @_wrapped.setter
+ def _wrapped(self, value):
+ setattr(self._parent, self._name, value)
def __getattr__(self, attr):
- return getattr(self.wrapped, attr)
+ return getattr(self._wrapped, attr)
+
+
+ def __contains__(self, value):
+ return self._wrapped.__contains__(value)
+
+ def __iter__(self):
+ return self._wrapped.__iter__()
+
+ def __len__(self):
+ return self._wrapped.__len__()
+
+
+ def __eq__(self, other):
+ if isinstance(other, set_proxy):
+ return self._wrapped == other._wrapped
+
+ else:
+ return self._wrapped == other
+
+ def __ne__(self, other):
+ if isinstance(other, set_proxy):
+ return self._wrapped != other._wrapped
+
+ else:
+ return self._wrapped != other
+
+ def __lt__(self, other):
+ if isinstance(other, set_proxy):
+ return self._wrapped < other._wrapped
+
+ else:
+ return self._wrapped < other
+
+ def __le__(self, other):
+ if isinstance(other, set_proxy):
+ return self._wrapped <= other._wrapped
+
+ else:
+ return self._wrapped <= other
+
+ def __gt__(self, other):
+ if isinstance(other, set_proxy):
+ return self._wrapped > other._wrapped
+
+ else:
+ return self._wrapped > other
+
+ def __ge__(self, other):
+ if isinstance(other, set_proxy):
+ return self._wrapped >= other._wrapped
+
+ else:
+ return self._wrapped >= other
+
+
+ if sys.version_info[0] == 2:
+ def __cmp__(self, other):
+ if isinstance(other, set_proxy):
+ return cmp(self._wrapped, other._wrapped)
+
+ else:
+ return cmp(self._wrapped, other)
def add(self, item):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueUnionSetMutation,
- set(item),
+ set([item]),
)
try:
self._wrapped.add(item)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueUnionSetMutation,
- set(item),
+ set([item]),
)
def clear(self):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
object = set(self._wrapped)
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
@@ -677,13 +768,16 @@
try:
self._wrapped.clear()
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
object
)
def difference_update(self, *others):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
s = set()
s.update(*others)
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
@@ -695,7 +789,7 @@
self._wrapped.difference_update(s)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
s
@@ -703,38 +797,47 @@
def discard(self, item):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
- set(item)
+ set([item])
)
try:
- self._wrapped.discard(s)
+ self._wrapped.discard(item)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
- set(item)
+ set([item])
)
def intersection_update(self, other):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueIntersectSetMutation,
- set(item)
+ set([item])
)
try:
self._wrapped.intersection_update(s)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueIntersectSetMutation,
- set(item)
+ set([item])
)
def pop(self):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
try:
v = iter(self).next()
except KeyError:
@@ -744,44 +847,75 @@
def remove(self, item):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
- set(item)
+ set([item])
)
try:
- self._wrapped.remove(s)
+ self._wrapped.remove(item)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
- set(item)
+ set([item])
)
def symmetric_difference_update(self, other):
+ # NOTE: This method does not call the corresponding method
+ # of the wrapped set to ensure that we generate the right
+ # notifications.
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
other = set(other)
- s = set()
- for item in other:
- if item in self:
- s.add(item)
+
+ to_add = set()
+ to_remove = set()
+ for o in other:
+ if o in self:
+ to_remove.add(o)
+ else:
+ to_add.add(o)
self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueMinusSetMutation,
- s
+ to_remove
)
try:
- self._wrapped.symmetric_difference_update(other)
+ self._wrapped.difference_update(to_remove)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
+ self._name,
+ NSKeyValueMinusSetMutation,
+ to_remove
+ )
+
+ self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
self._name,
- NSKeyValueMinusSetMutation,
- s
+ NSKeyValueUnionSetMutation,
+ to_add
+ )
+ try:
+ self._wrapped.update(to_add)
+
+ finally:
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
+ self._name,
+ NSKeyValueUnionSetMutation,
+ to_add
)
def update(self, *others):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
s = set()
s.update(*others)
@@ -794,42 +928,81 @@
self._wrapped.update(s)
finally:
- self._parent.willChangeValueForKey_withSetMutation_usingObjects_(
+ self._parent.didChangeValueForKey_withSetMutation_usingObjects_(
self._name,
NSKeyValueUnionSetMutation,
s
)
+ def __or__(self, other):
+ return self._wrapped | other
+
+ def __and__(self, other):
+ return self._wrapped & other
+
+ def __xor__(self, other):
+ return self._wrapped ^ other
+
+ def __sub__(self, other):
+ return self._wrapped - other
def __ior__(self, other):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
return self|other
def __isub__(self, other):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
return self-other
def __ixor__(self, other):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
return self^other
def __iand__(self, other):
+ if self._ro:
+ raise ValueError("Property '%s' is read-only"%(self._name,))
+
return self&other
class set_property (object_property):
- def __get__(self):
- v = object_property.__get__(self)
+ def __init__(self, name=None,
+ read_only=False, copy=True, dynamic=False,
+ ivar=None, depends_on=None):
+ super(set_property, self).__init__(name,
+ read_only=read_only,
+ copy=copy, dynamic=dynamic,
+ ivar=ivar, depends_on=depends_on)
+
+ def __get__(self, object, owner):
+ v = object_property.__get__(self, object, owner)
if v is None:
v = set()
- object_property.__set__(self, v)
- return set_proxy(self._name, v, self._ro)
+ object_property.__set__(self, object, v)
+ return set_proxy(self._name, object, self, self._ro)
+
+ def __getvalue__(self, object):
+ v = object_property.__get__(self, object, None)
+ if v is None:
+ v = set()
+ object_property.__set__(self, object, v)
+ return v
NSMutableDictionary = lookUpClass('NSMutableDictionary')
class dict_property (object_property):
- def __get__(self):
- v = object_property.__get__(self)
+ def __get__(self, object, owner):
+ v = object_property.__get__(self, object, owner)
if v is None:
v = NSMutableDictionary.alloc().init()
- object_property.__set__(self, v)
- return dict_proxy(self._name, v, self._ro)
+ object_property.__set__(self, object, v)
+ return object_property.__get__(self, object, owner)
+
Modified: trunk/pyobjc/pyobjc-core/PyObjCTest/loader.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/PyObjCTest/loader.py (original)
+++ trunk/pyobjc/pyobjc-core/PyObjCTest/loader.py Tue Jun 29 08:45:48 2010
@@ -53,7 +53,8 @@
def makeTestSuite():
- topdir = dirname(dirname(__file__))
+ import __main__
+ topdir = dirname(__main__.__file__)
if sys.version_info[0] == 3:
del sys.path[1]
deja_topdir = dirname(dirname(topdir))
Modified: trunk/pyobjc/pyobjc-core/PyObjCTest/test_array_property.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/PyObjCTest/test_array_property.py (original)
+++ trunk/pyobjc/pyobjc-core/PyObjCTest/test_array_property.py Tue Jun 29 08:45:48 2010
@@ -586,6 +586,13 @@
self.fail("ValueError not raised")
+ def testAssingmentInteraction(self):
+ o = TestArrayPropertyHelper.alloc().init()
+ array = o.array
+
+ o.array.append(1)
+ self.assertEquals(len(o.array), 1)
+ self.assertEquals(len(array), 1)
if __name__ == "__main__":
main()
Modified: trunk/pyobjc/pyobjc-core/PyObjCTest/test_dict_property.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/PyObjCTest/test_dict_property.py (original)
+++ trunk/pyobjc/pyobjc-core/PyObjCTest/test_dict_property.py Tue Jun 29 08:45:48 2010
@@ -1,11 +1,48 @@
from PyObjCTools.TestSupport import *
+from test_object_property import OCObserve
+import objc
+NSObject = objc.lookUpClass('NSObject')
+
+class TestDictPropertyHelper (NSObject):
+ aDict = objc.dict_property()
class TestDictProperty (TestCase):
- def testMissing(self):
- self.fail("Implement tests")
+ # objc.dict_property is currently just an object_property with a default value
+
+ def testDefault(self):
+ observer = OCObserve.alloc().init()
+
+ o = TestDictPropertyHelper.alloc().init()
+ observer.register(o, 'aDict')
+ try:
+ self.assertEquals(len(o.aDict), 0)
+ self.assertEquals(o.aDict, {})
+ self.assertEquals(len(observer.values), 0)
+
+ o.aDict['key'] = 42
+ self.assertEquals(len(observer.values), 0)
+
+ observer.register(o, 'aDict.key')
+
+ o.aDict['key'] = 43
+ self.assertEquals(len(observer.values), 1)
+
+ self.assertNotIn('indexes', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], 42)
+ self.assertEquals(observer.values[-1][-1]['new'], 43)
+
+ del o.aDict['key']
+
+ self.assertEquals(len(observer.values), 2)
+ self.assertNotIn('indexes', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], 43)
+ self.assertEquals(observer.values[-1][-1]['new'], None)
+ finally:
+ observer.unregister(o, 'aDict')
+ observer.unregister(o, 'aDict.key')
if __name__ == "__main__":
main()
Modified: trunk/pyobjc/pyobjc-core/PyObjCTest/test_object_property.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/PyObjCTest/test_object_property.py (original)
+++ trunk/pyobjc/pyobjc-core/PyObjCTest/test_object_property.py Tue Jun 29 08:45:48 2010
@@ -24,11 +24,13 @@
def init(self):
self = super(OCObserve, self).init()
self.values = []
+ self.registrations = []
return self
def register(self, object, keypath):
object.addObserver_forKeyPath_options_context_(
self, keypath, 0x3, None)
+ self.registrations.append((object, keypath))
def unregister(self, object, keypath):
object.removeObserver_forKeyPath_(self, keypath)
@@ -37,6 +39,14 @@
self, keypath, object, change, context):
self.values.append((object, keypath, change))
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ for o, k in self.registrations:
+ self.unregister(o, k)
+ self.registrations = []
+
class TestObjectProperty (TestCase):
def testCreation(self):
Modified: trunk/pyobjc/pyobjc-core/PyObjCTest/test_set_property.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/PyObjCTest/test_set_property.py (original)
+++ trunk/pyobjc/pyobjc-core/PyObjCTest/test_set_property.py Tue Jun 29 08:45:48 2010
@@ -1,10 +1,219 @@
from PyObjCTools.TestSupport import *
+import objc
+from test_object_property import OCObserve
+NSObject = objc.lookUpClass('NSObject')
+
+class TestSetPropertyHelper (NSObject):
+ aSet = objc.set_property()
class TestSetProperty (TestCase):
- def testMissing(self):
- self.fail("Implement tests")
+ def testCopying(self):
+ o = TestSetPropertyHelper.alloc().init()
+ aSet = set([1,2])
+ o.aSet = aSet
+
+ self.assertEquals(len(o.aSet), 2)
+ self.assertEquals(len(aSet), 2)
+ aSet.add(3)
+ self.assertEquals(len(o.aSet), 2)
+ self.assertEquals(len(aSet), 3)
+
+ def testDefault(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+
+ observer.register(o, 'aSet')
+
+ o.aSet = set()
+ self.assertEquals(len(observer.values), 1)
+
+ self.assertEquals(len(o.aSet), 0)
+ o.aSet.add('a')
+ o.aSet.add('b')
+ self.assertEquals(len(o.aSet), 2)
+ self.assertEquals(len(observer.values), 3)
+
+ self.assertEquals(observer.values[-2][-1]['kind'], 2)
+ self.assertNotIn('old', observer.values[-2][-1])
+ self.assertEquals(observer.values[-2][-1]['new'], set('a'))
+
+ self.assertEquals(observer.values[-1][-1]['kind'], 2)
+ self.assertNotIn('old', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['new'], set('b'))
+
+ v = list(o.aSet)
+ v.sort()
+ self.assertEquals(v, ['a', 'b'])
+
+ self.assertEqual(o.aSet, set(['a', 'b']))
+
+ proxy = o.aSet
+
+
+ o.aSet.clear()
+ self.assertEquals(len(o.aSet), 0)
+ self.assertEquals(len(proxy), 0)
+
+ self.assertEquals(len(observer.values), 4)
+ self.assertEquals(observer.values[-1][-1]['old'], set(['a', 'b']))
+ self.assertNotIn('new', observer.values[-1][-1])
+
+ def testDifferenceUpdate(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+
+ o.aSet.add(1)
+ o.aSet.add(2)
+ o.aSet.add(3)
+
+ observer.register(o, 'aSet')
+
+ o.aSet.difference_update(set([1,4]))
+ self.assertEquals(o.aSet, set([2,3]))
+
+ self.assertEquals(len(observer.values), 1)
+ self.assertEquals(observer.values[-1][-1]['kind'], 3)
+ self.assertNotIn('new', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], set([1]))
+
+ def testSymmetricDifferenceUpdate(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+
+ o.aSet = set([1,2,3])
+
+ observer.register(o, 'aSet')
+
+ self.assertEquals(len(observer.values), 0)
+ o.aSet.symmetric_difference_update(set([1,4]))
+ self.assertEquals(o.aSet, set([2, 3, 4]))
+
+ self.assertEquals(len(observer.values), 2)
+
+ haveAdd = False
+ haveRemove = False
+
+ for i in 0, 1:
+ if observer.values[i][-1]['kind'] == 3:
+ # Remove
+ self.assertNotIn('new', observer.values[i][-1])
+ self.assertEquals(observer.values[i][-1]['old'], set([1]))
+ haveRemove = True
+
+ elif observer.values[i][-1]['kind'] == 2:
+ # Remove
+ self.assertNotIn('old', observer.values[i][-1])
+ self.assertEquals(observer.values[i][-1]['new'], set([4]))
+ haveAdd = True
+
+ else:
+ self.fail("Unexpected update kind")
+
+ if not haveAdd and haveRemove:
+ self.fail("Do not have both an add and remove notification")
+
+ def testUpdate(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+ observer.register(o, 'aSet')
+
+ o.aSet.update([1,2,3])
+ self.assertEquals(len(observer.values), 1)
+ self.assertEquals(observer.values[-1][-1]['kind'], 2)
+ self.assertNotIn('old', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['new'], set([1, 2, 3]))
+
+ o.aSet.update(set([3,4,5]))
+ self.assertEquals(len(observer.values), 2)
+ self.assertEquals(observer.values[-1][-1]['kind'], 2)
+ self.assertNotIn('old', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['new'], set([4, 5]))
+
+
+
+ def testAddDiscard(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+ observer.register(o, 'aSet')
+
+ o.aSet.add(1)
+ self.assertEquals(len(observer.values), 1)
+ self.assertNotIn('old', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['new'], set([1]))
+
+ o.aSet.discard(1)
+ self.assertEquals(len(observer.values), 2)
+ self.assertNotIn('new', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], set([1]))
+
+ o.aSet.discard(2)
+ self.assertEquals(len(observer.values), 3)
+ self.assertNotIn('new', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], set([]))
+
+
+ def testAddRemove(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+ observer.register(o, 'aSet')
+
+ o.aSet.add(1)
+ self.assertEquals(len(observer.values), 1)
+ self.assertNotIn('old', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['new'], set([1]))
+
+ o.aSet.remove(1)
+ self.assertEquals(len(observer.values), 2)
+ self.assertNotIn('new', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], set([1]))
+
+ self.assertRaises(KeyError, o.aSet.remove, 2)
+ self.assertEquals(len(observer.values), 3)
+ self.assertNotIn('new', observer.values[-1][-1])
+ self.assertEquals(observer.values[-1][-1]['old'], set([]))
+
+ def testInplace(self):
+ with OCObserve.alloc().init() as observer:
+ o = TestSetPropertyHelper.alloc().init()
+ o.aSet.add(1)
+ observer.register(o, 'aSet')
+
+
+ # The inplace operators aren't actually implemented, which means
+ # "o.aSet |= value" is actually "o.aSet = o.aSet | value" and
+ # we get the some KVO notificatons as when a new value is set.
+
+ o.aSet |= set([2,3])
+ self.assertEquals(o.aSet, set([1,2,3]))
+ self.assertEquals(len(observer.values), 1)
+ self.assertEquals(observer.values[-1][-1]['kind'], 1)
+ self.assertEquals(observer.values[-1][-1]['old'], set([1]))
+ self.assertEquals(observer.values[-1][-1]['new'], set([1,2,3]))
+
+ o.aSet &= set([3, 4])
+ self.assertEquals(o.aSet, set([3]))
+ self.assertEquals(len(observer.values), 2)
+ self.assertEquals(observer.values[-1][-1]['kind'], 1)
+ self.assertEquals(observer.values[-1][-1]['old'], set([1,2,3]))
+ self.assertEquals(observer.values[-1][-1]['new'], set([3]))
+
+ o.aSet -= set([3])
+ self.assertEquals(o.aSet, set([]))
+ self.assertEquals(len(observer.values), 3)
+ self.assertEquals(observer.values[-1][-1]['kind'], 1)
+ self.assertEquals(observer.values[-1][-1]['old'], set([3]))
+ self.assertEquals(observer.values[-1][-1]['new'], set())
+
+ o.aSet = set([1,2,3])
+ self.assertEquals(len(observer.values), 4)
+ o.aSet ^= set([1, 4])
+ self.assertEquals(o.aSet, set([2, 3, 4]))
+ self.assertEquals(len(observer.values), 5)
+ self.assertEquals(observer.values[-1][-1]['kind'], 1)
+ self.assertEquals(observer.values[-1][-1]['old'], set([1,2,3]))
+ self.assertEquals(observer.values[-1][-1]['new'], set([2,3,4]))
if __name__ == "__main__":
main()
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first