test_keyvalue.py :  » Development » PyObjC » trunk » pyobjc » pyobjc-framework-Cocoa » PyObjCTest » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » PyObjC 
PyObjC » trunk » pyobjc » pyobjc framework Cocoa » PyObjCTest » test_keyvalue.py
"""
Tests for the Key-Value Coding for hybrid python objects.

NOTE: Testcases here should be synchronized with the Key-Value Coding tests
in PyObjCTools.test.test_keyvalue and objc.test.test_keyvalue.

TODO:
    - This test uses C code, that code should be added to this package!
    - Tests that access properties in the parent Objective-C class!
    - More key-error tests, the tests don't cover all relevant code yet.
"""
import objc
from PyObjCTools.TestSupport import *
import sys
from PyObjCTest.testhelper import PyObjC_TestClass3
from Foundation import *

class KeyValueClass1 (NSObject):
    def init(self):
        self = super(KeyValueClass1, self).init()
        self.key3 = 3
        self._key4 = u"4"
        self.__private = u"private"
        return self

    def addMultiple(self):
        self.multiple = KeyValueClass1.alloc().init()
        self.multiple.level2 = KeyValueClass1.alloc().init()
        self.multiple.level2.level3 = KeyValueClass1.alloc().init()
        self.multiple.level2.level3.keyA = u"hello"
        self.multiple.level2.level3.keyB = u"world"

    def getKey1(self):
        return 1

    def key2(self):
        return 2

    def setKey4_(self, value):
        self._key4 = value * 4

    def setKey5_(self, value):
        self.key5 = value * 5

    def keyRaisingValueError(self):
        raise ValueError, "42"

    def keyRaisingNSUnknownKeyException(self):
        return self.valueForKey_("thisKeyDoesNotExist")

    def keyReturningSameSlector(self):
        return self.keyReturningSameSelector

    def keyReturningOtherSelector(self):
        return self.getKey1

class KeyValueClass1Explicit (NSObject):
    def init(self):
        self = super(KeyValueClass1Explicit, self).init()
        self._values = {}
        self._values[u'key3'] = 3
        self._values[u'key4'] = u"4"
        self._values['_private'] = u"private"
        return self

    def addMultiple(self):
        self._values["multiple"] = KeyValueClass1Explicit.alloc().init()
        self._values["multiple"]._values["level2"] = KeyValueClass1Explicit.alloc().init()
        self._values["multiple"]._values["level2"]._values["level3"] = KeyValueClass1Explicit.alloc().init()
        self._values["multiple"]._values["level2"]._values["level3"]._values["keyA"] = u"hello"
        self._values["multiple"]._values["level2"]._values["level3"]._values["keyB"] = u"world"

    def valueForKey_(self, key):
        if key == "key1":
            return 1

        elif key == "key2":
            return 2

        return self._values[key]

    def storedValueForKey_(self, key):
        return self.valueForKey_(key)

    def setValue_forKey_(self, value, key):
        if key == "key4":
            value = value * 4
        elif key == "key5":
            value = value * 5

        self._values[key] = value

    def takeStoredValue_forKey_(self, value, key):
        self.setValue_forKey_(value, key)

    def takeValue_forKey_(self, value, key):
        self.setValue_forKey_(value, key)

class KeyValueClass4 (NSObject):
    __slots__ = ('foo', )

    def init(self):
        self = super(KeyValueClass4, self).init()
        self.foo = u"foobar"
        return self

    # Definition for property 'bar'. Use odd names for the methods
    # because the KeyValue support recognizes the usual names.
    def read_bar(self):
        return self.foo + self.foo

    def write_bar (self, value):
        self.foo = value + value

    bar = property(read_bar, write_bar)

    roprop = property(lambda self: u"read-only")

class KVOClass(NSObject):
    def automaticallyNotifiesObserversForKey_(self, aKey):
        return objc.NO

    def test(self): return u"test"


class KeyValueObserver (NSObject):
    def init(self):
        self.observed = []
        return self

    def observeValueForKeyPath_ofObject_change_context_(
            self, keyPath, object, change, context):
        self.observed.append( (keyPath, object, change) )


class PyKeyValueCoding (TestCase):
    def testNoPrivateVars(self):
        # Private instance variables ('anObject.__value') are not accessible using
        # key-value coding.
        o = KeyValueClass1.alloc().init()
        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 0, o, u"private")

    def testValueForKey(self):
        o = KeyValueClass1.alloc().init()
        o.addMultiple()

        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key1"), 1)

        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key2"), 2)
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key3"), 3)
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key4"), "4")
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"multiple"), o.multiple)

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 0, o, u"nokey")

        self.assertRaises(ValueError, STUB.keyValue_forObject_key_, 0, o,
                u"keyRaisingValueError")
        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 0, o,
                u"keyRaisingNSUnknownKeyException")
        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 0, o,
                u"keyReturningSameSelector")

        obj = STUB.keyValue_forObject_key_( 0, o, u"keyReturningOtherSelector")
        self.assertIsInstance(obj, objc.selector)
        self.assertEqual(obj.selector, b"getKey1")
        self.assertIsObject(obj.self, o )
    def testValueForKey2(self):
        o = KeyValueClass4.alloc().init()

        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"foo"), u"foobar")
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"bar"), u"foobarfoobar")
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"roprop"), u"read-only")


    def testStoredValueForKey(self):
        o = KeyValueClass1.alloc().init()
        o.addMultiple()

        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key1"), 1)
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key2"), 2)
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key3"), 3)
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key4"), "4")
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"multiple"), o.multiple)

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 2, o, u"nokey")

    def testStoredValueForKey2(self):
        o = KeyValueClass4.alloc().init()

        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"foo"), u"foobar")
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"bar"), u"foobarfoobar")
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"roprop"), u"read-only")

    def testValueForKeyPath(self):
        o = KeyValueClass1.alloc().init()
        o.addMultiple()

        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple"), o.multiple)
        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple.level2"), o.multiple.level2)
        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple.level2.level3.keyA"),
            o.multiple.level2.level3.keyA)
        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple.level2.level3.keyB"),
            o.multiple.level2.level3.keyB)

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 1, o, u"multiple.level2.nokey")

    @max_os_level('10.5')
    def testValuesForKeys(self):
        o = KeyValueClass1.alloc().init()

        self.assertEqual(STUB.keyValue_forObject_key_(3, o, [u"key1", u"key2", u"key3", u"key4"]), { u"key1":1, u"key2":2, u"key3": 3, u"key4": u"4"} )

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 3, o, [u"key1", u"key3", u"nosuchkey"])

    @max_os_level('10.5')
    def testTakeValueForKey(self):
        o = KeyValueClass1.alloc().init()

        self.assertEqual(o.key3, 3)
        STUB.setKeyValue_forObject_key_value_(0, o, u'key3', u'drie')
        self.assertEqual(o.key3, u"drie")

        self.assertEqual(o._key4, u"4")
        STUB.setKeyValue_forObject_key_value_(0, o, u'key4', u'vier')
        self.assert_(not hasattr(o, u"key4"))
        self.assertEqual(o._key4, u"viervierviervier")

        o.key5 = 1
        STUB.setKeyValue_forObject_key_value_(0, o, u'key5', u'V')
        self.assertEqual(o.key5, u"VVVVV")

        self.assert_(not hasattr(o, u'key9'))
        STUB.setKeyValue_forObject_key_value_(0, o, u'key9', u'IX')
        self.assert_(hasattr(o, u'key9'))
        self.assertEqual(o.key9, u'IX')

    @max_os_level('10.5')
    def testTakeValueForKey2(self):
        o = KeyValueClass4.alloc().init()

        self.assertEqual(o.foo, u"foobar")
        STUB.setKeyValue_forObject_key_value_(0, o, u'foo', u'FOO')
        self.assertEqual(o.foo, u"FOO")

        self.assertRaises(KeyError, STUB.setKeyValue_forObject_key_value_, 0, o, u'key9', u'IX')


    def testTakeStoredValueForKey(self):
        o = KeyValueClass1.alloc().init()

        self.assertEqual(o.key3, 3)
        STUB.setKeyValue_forObject_key_value_(2, o, u'key3', u'drie')
        self.assertEqual(o.key3, u"drie")

        self.assertEqual(o._key4, u"4")
        STUB.setKeyValue_forObject_key_value_(2, o, u'key4', u'vier')
        self.assertEqual(o._key4, u"viervierviervier")

        o.key5 = 1
        STUB.setKeyValue_forObject_key_value_(2, o, u'key5', u'V')
        self.assertEqual(o.key5, u"VVVVV")

        self.assert_(not hasattr(o, u'key9'))
        STUB.setKeyValue_forObject_key_value_(2, o, u'key9', u'IX')
        self.assert_(hasattr(o, u'key9'))
        self.assertEqual(o.key9, u'IX')

    def testStoredTakeValueForKey2(self):
        o = KeyValueClass4.alloc().init()

        self.assertEqual(o.foo, u"foobar")
        STUB.setKeyValue_forObject_key_value_(2, o, u'foo', u'FOO')
        self.assertEqual(o.foo, u"FOO")

        self.assertRaises(KeyError, STUB.setKeyValue_forObject_key_value_, 2, o, u'key9', u'IX')
        self.assertRaises(KeyError, STUB.setKeyValue_forObject_key_value_, 2, o, u'roprop', u'IX')

    @max_os_level('10.5')
    def testTakeValuesFromDictionary(self):
        o = KeyValueClass1.alloc().init()

        self.assertEqual(o.key3, 3)
        self.assertEqual(o._key4, u"4")
        o.key5 = 1
        self.assert_(not hasattr(o, u'key9'))

        STUB.setKeyValue_forObject_key_value_(3, o, None,
            {
                u'key3': u'drie',
                u'key4': u'vier',
                u'key5': u'V',
                u'key9': u'IX',
            })

        self.assertEqual(o.key3, u"drie")
        self.assertEqual(o._key4, u"viervierviervier")
        self.assertEqual(o.key5, u"VVVVV")
        self.assert_(hasattr(o, u'key9'))
        self.assertEqual(o.key9, u'IX')

    @max_os_level('10.5')
    def testTakeValuesFromDictionary2(self):
        o = KeyValueClass4.alloc().init()

        self.assertEqual(o.foo, u"foobar")
        STUB.setKeyValue_forObject_key_value_(3, o, None, { u'foo': u'FOO' })
        self.assertEqual(o.foo, u"FOO")

        self.assertRaises(KeyError, STUB.setKeyValue_forObject_key_value_, 3, o, None, { u'key9':  u'IX' })
        self.assertRaises(KeyError, STUB.setKeyValue_forObject_key_value_, 3, o, None, { u'roprop':  u'IX' })

    @max_os_level('10.5')
    def testTakeValueForKeyPath(self):
        o = KeyValueClass1.alloc().init()
        o.addMultiple()

        self.assertEqual(o.multiple.level2.level3.keyA, u"hello")
        self.assertEqual(o.multiple.level2.level3.keyB, u"world")

        STUB.setKeyValue_forObject_key_value_(1, o, u"multiple.level2.level3.keyA", u"KeyAValue")
        self.assertEqual(o.multiple.level2.level3.keyA, u"KeyAValue")

        STUB.setKeyValue_forObject_key_value_(1, o, u"multiple.level2.level3.keyB", 9.999)
        self.assertEqual(o.multiple.level2.level3.keyB, 9.999)

    if hasattr(NSObject, u"willChangeValueForKey_"):
        # NSKeyValueObserving is only available on Panther and beyond
        def testKVO1(self):
            o = KVOClass.alloc().init()
            o.addObserver_forKeyPath_options_context_(self, u"test", 0, None)
            o.removeObserver_forKeyPath_(self, u"test")

        def testKVO2(self):
            """
            Check if observations work for python-based keys on ObjC classes
            """
            observer = KeyValueObserver.alloc().init()
            self.assertEqual(observer.observed, [])

            o = KeyValueClass1.alloc().init()

            o.addObserver_forKeyPath_options_context_(observer, u"key3", 0, 0)
            try:
                STUB.setKeyValue_forObject_key_value_(2, o, u'key3', u'drie')
                self.assertEqual(o.key3, u"drie")

                self.assertEqual(len(observer.observed), 1)

                keyPath, object, change = observer.observed[0]
                self.assertEqual(keyPath, u"key3")
                self.assert_(object is o)
                self.assertEqual(change, {NSKeyValueChangeKindKey: 1 })

            finally:
                o.removeObserver_forKeyPath_(observer, u'key3')

        def testKVO3(self):
            """
            Check if observations work for python-based keys on ObjC classes
            """
            observer = KeyValueObserver.alloc().init()
            self.assertEqual(observer.observed, [])

            o = KeyValueClass1.alloc().init()
            STUB.setKeyValue_forObject_key_value_(2, o, u'key3', u'three')

            o.addObserver_forKeyPath_options_context_(observer, u"key3",
                    NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld,
                    0)
            try:
                STUB.setKeyValue_forObject_key_value_(2, o, u'key3', u'drie')
                self.assertEqual(o.key3, u"drie")

                self.assertEqual(len(observer.observed), 1)

                keyPath, object, change = observer.observed[0]
                self.assertEqual(keyPath, u"key3")
                self.assert_(object is o)
                self.assertEqual(change,
                    {
                        NSKeyValueChangeKindKey:1,
                        NSKeyValueChangeNewKey:u'drie',
                        NSKeyValueChangeOldKey:u'three'
                    })

            finally:
                o.removeObserver_forKeyPath_(observer, u'key3')

class PyKeyValueCodingExplicit (TestCase):

    def testValueForKey(self):
        o = KeyValueClass1Explicit.alloc().init()
        o.addMultiple()

        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key1"), 1)

        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key2"), 2)
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key3"), 3)
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"key4"), "4")
        self.assertEqual(STUB.keyValue_forObject_key_(0, o, u"multiple"), o._values['multiple'])

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 0, o, u"nokey")

    def testStoredValueForKey(self):
        o = KeyValueClass1Explicit.alloc().init()
        o.addMultiple()

        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key1"), 1)
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key2"), 2)
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key3"), 3)
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"key4"), "4")
        self.assertEqual(STUB.keyValue_forObject_key_(2, o, u"multiple"), o._values['multiple'])

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 2, o, u"nokey")

    def testValueForKeyPath(self):
        o = KeyValueClass1Explicit.alloc().init()
        o.addMultiple()

        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple"), o._values['multiple'])
        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple.level2"), o._values['multiple']._values['level2'])
        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple.level2.level3.keyA"),
            o._values['multiple']._values['level2']._values['level3']._values['keyA'])
        self.assertEqual(STUB.keyValue_forObject_key_(1, o, u"multiple.level2.level3.keyB"),
            o._values['multiple']._values['level2']._values['level3']._values['keyB'])

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 1, o, u"multiple.level2.nokey")

    @max_os_level('10.5')
    def testValuesForKeys(self):
        o = KeyValueClass1Explicit.alloc().init()

        self.assertEqual(STUB.keyValue_forObject_key_(3, o, [u"key1", u"key2", u"key3", u"key4"]), { u"key1":1, u"key2":2, u"key3": 3, u"key4": u"4"} )

        self.assertRaises(KeyError, STUB.keyValue_forObject_key_, 3, o, [u"key1", u"key3", u"nosuchkey"])

    def testTakeValueForKey(self):
        o = KeyValueClass1Explicit.alloc().init()

        self.assertEqual(o._values['key3'], 3)
        STUB.setKeyValue_forObject_key_value_(0, o, u'key3', u'drie')
        self.assertEqual(o._values['key3'], u"drie")

        self.assertEqual(o._values['key4'], u"4")
        STUB.setKeyValue_forObject_key_value_(0, o, u'key4', u'vier')
        self.assert_(not hasattr(o, u"key4"))
        self.assertEqual(o._values['key4'], u"viervierviervier")

        o._values['key5'] = 1
        STUB.setKeyValue_forObject_key_value_(0, o, u'key5', u'V')
        self.assertEqual(o._values['key5'], u"VVVVV")

        self.assert_(not hasattr(o, u'key9'))
        self.assert_('key9' not in o._values)
        STUB.setKeyValue_forObject_key_value_(0, o, u'key9', u'IX')
        self.assert_(not hasattr(o, u'key9'))
        self.assert_('key9' in o._values)
        self.assertEqual(o._values['key9'], u'IX')

    def testTakeStoredValueForKey(self):
        o = KeyValueClass1Explicit.alloc().init()

        self.assertEqual(o._values['key3'], 3)
        STUB.setKeyValue_forObject_key_value_(2, o, u'key3', u'drie')
        self.assertEqual(o._values['key3'], u"drie")

        self.assertEqual(o._values['key4'], u"4")
        STUB.setKeyValue_forObject_key_value_(2, o, u'key4', u'vier')
        self.assertEqual(o._values['key4'], u"viervierviervier")

        o.key5 = 1
        STUB.setKeyValue_forObject_key_value_(2, o, u'key5', u'V')
        self.assertEqual(o._values['key5'], u"VVVVV")

        self.assert_('key9' not in o._values)
        STUB.setKeyValue_forObject_key_value_(2, o, u'key9', u'IX')
        self.assert_('key9' in o._values)
        self.assertEqual(o._values['key9'], u'IX')

    @max_os_level('10.5')
    def testTakeValuesFromDictionary(self):
        o = KeyValueClass1Explicit.alloc().init()

        self.assertEqual(o._values['key3'], 3)
        self.assertEqual(o._values['key4'], u"4")
        o._values['key5'] = 1
        self.assert_('key9' not in o._values)

        STUB.setKeyValue_forObject_key_value_(3, o, None,
            {
                u'key3': u'drie',
                u'key4': u'vier',
                u'key5': u'V',
                u'key9': u'IX',
            })

        self.assertEqual(o._values['key3'], u"drie")
        self.assertEqual(o._values['key4'], u"viervierviervier")
        self.assertEqual(o._values['key5'], u"VVVVV")
        self.assertEqual(o._values['key9'], u'IX')

    @max_os_level('10.5')
    def testTakeValueForKeyPath(self):
        o = KeyValueClass1Explicit.alloc().init()
        o.addMultiple()

        self.assertEqual(o._values['multiple']._values['level2']._values['level3']._values['keyA'], u"hello")
        self.assertEqual(o._values['multiple']._values['level2']._values['level3']._values['keyB'], u"world")

        STUB.setKeyValue_forObject_key_value_(1, o, u"multiple.level2.level3.keyA", u"KeyAValue")
        self.assertEqual(o._values['multiple']._values['level2']._values['level3']._values['keyA'], u"KeyAValue")

        STUB.setKeyValue_forObject_key_value_(1, o, u"multiple.level2.level3.keyB", 9.999)
        self.assertEqual(o._values['multiple']._values['level2']._values['level3']._values['keyB'], 9.999)


class TestBaseExceptions (TestCase):
    """
    Check that NSObject implementation of Key-Value coding raises the
    exception that we expect it to raise.
    """
    def testValueForKey(self):
        o = NSObject.alloc().init()

        self.assertRaises(KeyError, o.valueForKey_, u"unknownKey")

    def testStoredValueForKey(self):
        o = NSObject.alloc().init()

        self.assertRaises(KeyError, o.storedValueForKey_, u"unknownKey")

    def testTakeStoredValue(self):
        o = NSObject.alloc().init()

        self.assertRaises(KeyError,
            o.takeStoredValue_forKey_, u"value", u"unknownKey")



if __name__ == "__main__":
    main()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.