Beispiel #1
0
    def test_object_return(self):
        "If a method or field returns an object, you get an instance of that type returned"
        Example = ObjCClass('Example')
        example = Example.alloc().init()

        Thing = ObjCClass('Thing')
        thing = Thing.alloc().initWithName_value_('This is thing', 2)

        example.thing = thing

        the_thing = example.thing
        self.assertEqual(the_thing.toString(), "This is thing 2")
Beispiel #2
0
    def test_class_properties(self):
        "A Python class can have ObjC properties with synthesized getters and setters."

        NSURL = ObjCClass('NSURL')

        class URLBox(NSObject):

            url = objc_property(ObjCInstance)
            data = objc_property(ObjCInstance)

            @objc_method
            def getSchemeIfPresent(self):
                if self.url is not None:
                    return self.url.scheme
                return None

        box = URLBox.alloc().init()

        # Default property value is None
        self.assertIsNone(box.url)

        # Assign an object via synthesized property setter and call method that uses synthesized property getter
        url = NSURL.alloc().initWithString_('https://www.google.com')
        box.url = url
        self.assertEqual(box.getSchemeIfPresent(), 'https')

        # Assign None to dealloc property and see if method returns expected None
        box.url = None
        self.assertIsNone(box.getSchemeIfPresent())

        # Try composing URLs using constructors
        base = NSURL.URLWithString('https://pybee.org')
        full = NSURL.URLWithString('contributing/', relativeToURL=base)

        self.assertEqual(
            "Visit %s for details" % full.absoluteURL,
            "Visit https://pybee.org/contributing/ for details"
        )

        # ObjC type conversions are performed on property assignment.
        box.data = "Jabberwock"
        self.assertEqual(box.data, "Jabberwock")

        Example = ObjCClass('Example')
        example = Example.alloc().init()
        box.data = example
        self.assertEqual(box.data, example)

        box.data = None
        self.assertIsNone(box.data)
Beispiel #3
0
    def test_property_forcing(self):
        "An instance or property method can be explicitly declared as a property."
        Example = ObjCClass('Example')
        Example.declare_class_property('classMethod')
        Example.declare_class_property('classAmbiguous')
        Example.declare_property('instanceMethod')
        Example.declare_property('instanceAmbiguous')

        # A class method can be turned into a property
        self.assertEqual(Example.classMethod, 37)

        # An actual class property can be accessed as a property
        self.assertEqual(Example.classAmbiguous, 37)

        # An instance property can be accessed
        obj1 = Example.alloc().init()

        # An instance method can be turned into a property
        self.assertEqual(obj1.instanceMethod, 42)

        # An actual property can be accessed as a property
        self.assertEqual(obj1.instanceAmbiguous, 42)

        # Practical example: In Sierra, mainBundle was turned into a class property.
        # Previously, it was a method.
        NSBundle = ObjCClass('NSBundle')
        NSBundle.declare_class_property('mainBundle')
        self.assertFalse(callable(NSBundle.mainBundle), 'NSBundle.mainBundle should not be a method')
Beispiel #4
0
    def test_enum_argument(self):
        "An enumerated type can be used as an argument."
        Example = ObjCClass('Example')

        obj = Example.alloc().init()

        self.assertEqual(obj.accessBaseIntField(), 22)
        self.assertEqual(obj.accessIntField(), 33)

        class MyEnum(Enum):
            value1 = 8888
            value2 = 9999
            value3 = 3333
            value4 = 4444

        obj.mutateBaseIntFieldWithValue_(MyEnum.value1)
        obj.mutateIntFieldWithValue_(MyEnum.value2)

        self.assertEqual(obj.accessBaseIntField(), MyEnum.value1.value)
        self.assertEqual(obj.accessIntField(), MyEnum.value2.value)

        obj.baseIntField = MyEnum.value3
        obj.intField = MyEnum.value4

        self.assertEqual(obj.accessBaseIntField(), MyEnum.value3.value)
        self.assertEqual(obj.accessIntField(), MyEnum.value4.value)
Beispiel #5
0
    def test_number_return(self):
        "If a method or field returns a NSNumber, it is converted back to native types"
        Example = ObjCClass('Example')
        example = Example.alloc().init()

        self.assertEqual(example.theAnswer(), 42)
        self.assertAlmostEqual(example.twopi(), 2.0 * math.pi, 5)
Beispiel #6
0
    def test_no_convert_return(self):
        Example = ObjCClass("Example")
        example = Example.alloc().init()

        res = example.toString(convert_result=False)
        self.assertNotIsInstance(res, ObjCInstance)
        self.assertEqual(str(ObjCInstance(res)), "This is an ObjC Example object")
Beispiel #7
0
    def test_block_receiver_unannotated(self):
        BlockReceiverExample = ObjCClass("BlockReceiverExample")
        instance = BlockReceiverExample.alloc().init()

        def block(a, b):
            return a + b
        with self.assertRaises(ValueError):
            instance.receiverMethod_(block)
Beispiel #8
0
    def test_decimal_method(self):
        "A method with a NSDecimalNumber arguments can be handled."
        Example = ObjCClass('Example')
        example = Example.alloc().init()

        result = example.areaOfTriangleWithWidth_andHeight_(Decimal('3.0'), Decimal('4.0'))
        self.assertEqual(result, Decimal('6.0'))
        self.assertIsInstance(result, Decimal, 'Result should be a Decimal')
Beispiel #9
0
    def test_struct_return_send(self):
        "Methods returning structs of different sizes by value can be handled when using send_message."
        Example = ObjCClass('Example')
        example = Example.alloc().init()

        self.assertEqual(send_message(example, "intSizedStruct", restype=struct_int_sized).x, b"abc")
        self.assertEqual(send_message(example, "oddlySizedStruct", restype=struct_oddly_sized).x, b"abcd")
        self.assertEqual(send_message(example, "largeStruct", restype=struct_large).x, b"abcdefghijklmnop")
Beispiel #10
0
    def test_argument(self):
        Example = ObjCClass("Example")
        example = Example.alloc().init()

        a = self.make_array(self.py_list)
        # Call a method with an NSArray instance
        self.assertEqual(example.processArray(a), 'two')
        # Call the same method with the Python list
        self.assertEqual(example.processArray(self.py_list), 'two')
Beispiel #11
0
    def test_block_round_trip(self):
        BlockRoundTrip = ObjCClass("BlockRoundTrip")
        instance = BlockRoundTrip.alloc().init()

        def block(a: int, b: int) -> int:
            return a + b

        returned_block = instance.roundTrip_(block)
        self.assertEqual(returned_block(8, 9), 17)
Beispiel #12
0
    def test_property(self):
        Example = ObjCClass("Example")
        example = Example.alloc().init()

        a = self.make_array(self.py_list)
        example.array = a

        self.assertEqual(example.array, self.py_list)
        self.assertIsInstance(example.array, ObjCListInstance)
        self.assertEqual(example.array[1], 'two')
Beispiel #13
0
    def test_block_receiver_explicit(self):
        BlockReceiverExample = ObjCClass("BlockReceiverExample")
        instance = BlockReceiverExample.alloc().init()

        values = []

        block = Block(lambda a, b: values.append(a + b), None, int, int)
        instance.receiverMethod_(block)

        self.assertEqual(values, [27])
Beispiel #14
0
 def test_block_delegate_auto(self):
     class DelegateAuto(NSObject):
         @objc_method
         def exampleMethod_(self, block: objc_block):
             block(4, 5)
     BlockObjectExample = ObjCClass("BlockObjectExample")
     delegate = DelegateAuto.alloc().init()
     instance = BlockObjectExample.alloc().initWithDelegate_(delegate)
     result = instance.blockExample()
     self.assertEqual(result, 9)
Beispiel #15
0
 def test_block_delegate_method_manual_pytypes(self):
     class DelegateManualPY(NSObject):
         @objc_method
         def exampleMethod_(self, block):
             ObjCBlock(block, None, int, int)(2, 3)
     BlockObjectExample = ObjCClass("BlockObjectExample")
     delegate = DelegateManualPY.alloc().init()
     instance = BlockObjectExample.alloc().initWithDelegate_(delegate)
     result = instance.blockExample()
     self.assertEqual(result, 5)
Beispiel #16
0
    def test_property(self):
        Example = ObjCClass("Example")
        example = Example.alloc().init()

        d = self.make_dictionary(self.py_dict)
        example.dict = d

        self.assertEqual(example.dict, self.py_dict)
        self.assertIsInstance(example.dict, ObjCDictInstance)
        self.assertEqual(example.dict['one'], 'ONE')
Beispiel #17
0
    def test_polymorphic_constructor(self):
        "Check that the right constructor is activated based on arguments used"
        Example = ObjCClass('Example')

        obj1 = Example.alloc().init()
        obj2 = Example.alloc().initWithIntValue_(2242)
        obj3 = Example.alloc().initWithBaseIntValue_intValue_(3342, 3337)

        self.assertEqual(obj1.baseIntField, 22)
        self.assertEqual(obj1.intField, 33)

        self.assertEqual(obj2.baseIntField, 44)
        self.assertEqual(obj2.intField, 2242)

        self.assertEqual(obj3.baseIntField, 3342)
        self.assertEqual(obj3.intField, 3337)

        # Protected constructors can't be invoked
        with self.assertRaises(AttributeError):
            Example.alloc().initWithString_("Hello")
Beispiel #18
0
    def test_static_access_non_static(self):
        "An instance field/method cannot be accessed from the static context"
        Example = ObjCClass('Example')

        obj = Example.alloc().init()

        with self.assertRaises(AttributeError):
            obj.staticIntField

        with self.assertRaises(AttributeError):
            obj.get_staticIntField()
Beispiel #19
0
    def test_block_receiver(self):
        BlockReceiverExample = ObjCClass("BlockReceiverExample")
        instance = BlockReceiverExample.alloc().init()

        values = []

        def block(a: int, b: int) -> None:
            values.append(a + b)
        instance.receiverMethod_(block)

        self.assertEqual(values, [27])
Beispiel #20
0
 def test_double_method_send(self):
     "A method with a double argument can be handled by send_message."
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertAlmostEqual(
         send_message(
             example, "areaOfCircle:", 1.5,
             restype=c_double,
             argtypes=[c_double]
         ),
         1.5 * math.pi, 5
     )
Beispiel #21
0
    def test_non_existent_method(self):
        "An attribute error is raised if you invoke a non-existent method."
        Example = ObjCClass('Example')

        obj1 = Example.alloc().init()

        # Non-existent methods raise an error.
        with self.assertRaises(AttributeError):
            obj1.method_doesnt_exist()

        # Cache warming doesn't affect anything.
        with self.assertRaises(AttributeError):
            obj1.method_doesnt_exist()
Beispiel #22
0
    def test_struct_return(self):
        "Methods returning structs of different sizes by value can be handled."
        Example = ObjCClass('Example')
        example = Example.alloc().init()

        types.register_encoding(b'{int_sized=[4c]}', struct_int_sized)
        self.assertEqual(example.intSizedStruct().x, b"abc")

        types.register_encoding(b'{oddly_sized=[5c]}', struct_oddly_sized)
        self.assertEqual(example.oddlySizedStruct().x, b"abcd")

        types.register_encoding(b'{large=[17c]}', struct_large)
        self.assertEqual(example.largeStruct().x, b"abcdefghijklmnop")
Beispiel #23
0
    def test_multitype_list_property(self):
        class MultitypeListContainer(NSObject):
            data = objc_property()

        Example = ObjCClass('Example')
        example = Example.alloc().init()

        # All types can be stored in a list.
        obj = MultitypeListContainer.alloc().init()

        obj.data = [4, True, 'Hello', example]
        self.assertEqual(obj.data, [4, True, 'Hello', example])
        self.assertIsInstance(obj.data, ObjCListInstance)
Beispiel #24
0
    def test_method_send(self):
        "An instance method can be invoked with send_message."
        Example = ObjCClass('Example')

        obj = Example.alloc().init()

        self.assertEqual(send_message(obj, "accessBaseIntField", restype=c_int), 22)
        self.assertEqual(send_message(obj, "accessIntField", restype=c_int), 33)

        send_message(obj, "mutateBaseIntFieldWithValue:", 8888, restype=None, argtypes=[c_int])
        send_message(obj, "mutateIntFieldWithValue:", 9999, restype=None, argtypes=[c_int])

        self.assertEqual(send_message(obj, "accessBaseIntField", restype=c_int), 8888)
        self.assertEqual(send_message(obj, "accessIntField", restype=c_int), 9999)
Beispiel #25
0
    def test_method(self):
        "An instance method can be invoked."
        Example = ObjCClass('Example')

        obj = Example.alloc().init()

        self.assertEqual(obj.accessBaseIntField(), 22)
        self.assertEqual(obj.accessIntField(), 33)

        obj.mutateBaseIntFieldWithValue_(8888)
        obj.mutateIntFieldWithValue_(9999)

        self.assertEqual(obj.accessBaseIntField(), 8888)
        self.assertEqual(obj.accessIntField(), 9999)
Beispiel #26
0
    def test_field(self):
        "A field on an instance can be accessed and mutated"

        Example = ObjCClass('Example')

        obj = Example.alloc().init()

        self.assertEqual(obj.baseIntField, 22)
        self.assertEqual(obj.intField, 33)

        obj.baseIntField = 8888
        obj.intField = 9999

        self.assertEqual(obj.baseIntField, 8888)
        self.assertEqual(obj.intField, 9999)
Beispiel #27
0
    def test_block_delegate_auto_struct(self):
        class BlockStruct(Structure):
            _fields_ = [
                ('a', c_int),
                ('b', c_int),
            ]

        class DelegateAutoStruct(NSObject):
            @objc_method
            def structBlockMethod_(self, block: objc_block) -> int:
                return block(BlockStruct(42, 43))
        BlockObjectExample = ObjCClass("BlockObjectExample")
        delegate = DelegateAutoStruct.alloc().init()
        instance = BlockObjectExample.alloc().initWithDelegate_(delegate)
        result = instance.structBlockExample()
        self.assertEqual(result, 85)
Beispiel #28
0
    def test_argument(self):
        Example = ObjCClass("Example")
        example = Example.alloc().init()

        d = self.make_dictionary(self.py_dict)
        # Call a method with an NSDictionary instance
        self.assertIsNone(example.processDictionary(d))
        # Call the same method with the raw Python dictionary
        self.assertIsNone(example.processDictionary(self.py_dict))

        raw = {'data': 'stuff', 'other': 'gadgets'}
        d = self.make_dictionary(raw)
        # Call a method with an NSDictionary instance
        self.assertEqual(example.processDictionary(d), 'stuff')
        # Call the same method with the raw Python dictionary
        self.assertEqual(example.processDictionary(raw), 'stuff')
Beispiel #29
0
    def test_mutator_like_method(self):
        "A method that looks like a mutator doesn't confuse issues."
        Example = ObjCClass('Example')

        obj1 = Example.alloc().init()

        # setSpecialValue: looks like it might be a mutator
        # for a specialValue property, but this property doesn't exist.

        # We can invoke the method directly...
        obj1.setSpecialValue_(42)

        # ... but retrieving like a property is an error:
        with self.assertRaises(AttributeError):
            obj1.specialValue

        # ... and mutating like a property is an error:
        with self.assertRaises(AttributeError):
            obj1.specialValue = 37
Beispiel #30
0
    def test_mutator_like_method(self):
        "A method that looks like a mutator doesn't confuse issues."
        Example = ObjCClass('Example')

        obj1 = Example.alloc().init()

        # setSpecialValue: looks like it might be a mutator
        # for a specialValue property, but this property doesn't exist.

        # We can invoke the method directly...
        obj1.setSpecialValue_(42)

        # ... but retrieving like a property is an error
        with self.assertRaises(AttributeError):
            obj1.specialValue

        # ...until you set it explicitly...
        obj1.specialValue = 37

        # ...at which point it's fair game to be retrieved.
        self.assertEqual(obj1.specialValue, 37)
Beispiel #31
0
 def test_string_return(self):
     "If a method or field returns a string, you get a Python string back"
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertEqual(example.toString(), "This is an ObjC Example object")
Beispiel #32
0
 def test_constant_string_return(self):
     "If a method or field returns a *constant* string, you get a Python string back"
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertEqual(example.smiley(), "%-)")
Beispiel #33
0
"""
Save values on disk

This module makes possible to save values on disk. Values are shared between the Today Widget and the main app.
Values are stored in a JSON dictionary, so it's not possible to save every type of data.
"""

from rubicon.objc import ObjCClass
import json


NSUserDefaults = ObjCClass("NSUserDefaults")
userDefaults = NSUserDefaults.alloc().initWithSuiteName("group.pyto")


if userDefaults.valueForKey("userKeys") is None:
    userDefaults.setValue("{}", forKey="userKeys")


def __dictionary__():
    return json.loads(str(userDefaults.valueForKey("userKeys")))


def get(key: str):
    """
    Returns the value stored with the given key.

    :param key: The key identifying the value.
    """

    return __dictionary__()[key]
Beispiel #34
0
 def test_float_method(self):
     "A method with a float argument can be handled."
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertEqual(example.areaOfSquare_(1.5), 2.25)
Beispiel #35
0
 def test_float_method_send(self):
     "A method with a float argument can be handled by send_message."
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertEqual(send_message(example, "areaOfSquare:", 1.5, restype=c_float, argtypes=[c_float]), 2.25)
Beispiel #36
0
    def test_interface(self):
        "An ObjC protocol implementation can be defined in Python."

        results = {}

        NSObject = ObjCClass('NSObject')

        class Handler(NSObject):
            @objc_method
            def initWithValue_(self, value: int):
                self.value = value
                return self

            @objc_method
            def peek_withValue_(self, example, value: int) -> None:
                results['string'] = example.toString() + " peeked"
                results['int'] = value + self.value

            @objc_method
            def poke_withValue_(self, example, value: int) -> None:
                results['string'] = example.toString() + " poked"
                results['int'] = value + self.value

            @objc_method
            def reverse_(self, input):
                return ''.join(reversed(input))

            @objc_method
            def message(self):
                return "Alea iacta est."

            @objc_classmethod
            def fiddle_(cls, value: int) -> None:
                results['string'] = "Fiddled with it"
                results['int'] = value

        # Create two handler instances so we can check the right one
        # is being invoked.
        handler1 = Handler.alloc().initWithValue_(5)
        handler2 = Handler.alloc().initWithValue_(10)

        # Create an Example object, and register a handler with it.
        Example = ObjCClass('Example')
        example = Example.alloc().init()
        example.callback = handler2

        # Check some Python-side attributes
        self.assertEqual(handler1.value, 5)
        self.assertEqual(handler2.value, 10)

        # Invoke the callback; check that the results have been peeked as expected
        example.testPeek_(42)

        self.assertEqual(results['string'], 'This is an ObjC Example object peeked')
        self.assertEqual(results['int'], 52)

        example.testPoke_(37)

        self.assertEqual(results['string'], 'This is an ObjC Example object poked')
        self.assertEqual(results['int'], 47)

        self.assertEqual(example.getMessage(), 'Alea iacta est.')

        self.assertEqual(example.reverseIt_('Alea iacta est.'), '.tse atcai aelA')

        Handler.fiddle_(99)

        self.assertEqual(results['string'], 'Fiddled with it')
        self.assertEqual(results['int'], 99)
Beispiel #37
0
 def test_block_receiver_lambda(self):
     BlockReceiverExample = ObjCClass("BlockReceiverExample")
     instance = BlockReceiverExample.alloc().init()
     with self.assertRaises(ValueError):
         instance.receiverMethod_(lambda a, b: a + b)
Beispiel #38
0
 def test_double_method_send(self):
     "A method with a double argument can be handled by send_message."
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertAlmostEqual(send_message(example, "areaOfCircle:", 1.5, restype=c_double, argtypes=[c_double]), 1.5 * math.pi, 5)
Beispiel #39
0
    def test_interface_return_struct(self):
        "An ObjC protocol implementation that returns values by struct can be defined in Python."

        results = {}
        Thing = ObjCClass("Thing")

        class StructReturnHandler(Thing):
            @objc_method
            def initWithValue_(self, value):
                self.value = py_from_ns(value)
                return self

            @objc_method
            def computeSize_(self, input: NSSize) -> NSSize:
                results['size'] = True
                sup = send_super(__class__, self, 'computeSize:', input, restype=NSSize, argtypes=[NSSize])
                return NSSize(input.width + self.value, sup.height)

            @objc_method
            def computeRect_(self, input: NSRect) -> NSRect:
                results['rect'] = True
                sup = send_super(__class__, self, 'computeRect:', input, restype=NSRect, argtypes=[NSRect])
                return NSMakeRect(
                    input.origin.y + self.value, sup.origin.x,
                    input.size.height + self.value, sup.size.width
                )

            # Register a second method returning NSSize. Don't
            # have to use it - just have to register that it exists.
            @objc_method
            def origin(self) -> NSSize:
                return NSSize(0, 0)

        # Create two handler instances so we can check the right one
        # is being invoked.
        handler1 = StructReturnHandler.alloc().initWithValue_(5)
        handler2 = StructReturnHandler.alloc().initWithValue_(10)

        outSize = handler1.computeSize(NSSize(20, 30))
        self.assertEqual(outSize.width, 25)
        self.assertEqual(outSize.height, 90)
        self.assertTrue(results.get('size'))

        outRect = handler2.computeRect(NSMakeRect(10, 20, 30, 40))
        self.assertEqual(outRect.origin.x, 30)
        self.assertEqual(outRect.origin.y, 110)
        self.assertEqual(outRect.size.width, 50)
        self.assertEqual(outRect.size.height, 60)
        self.assertTrue(results.get('rect'))

        # Invoke a method through an interface.
        Example = ObjCClass("Example")
        obj = Example.alloc().init()

        # Test the base class directly
        thing1 = Thing.alloc().init()
        obj.thing = thing1
        outSize = obj.testThing(10)
        self.assertEqual(outSize.width, 0)
        self.assertEqual(outSize.height, 30)

        # Test the python handler
        obj.thing = handler1
        outSize = obj.testThing(15)
        self.assertEqual(outSize.width, 5)
        self.assertEqual(outSize.height, 45)
Beispiel #40
0
 def test_string_argument(self):
     "A method with a string argument can be passed."
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertEqual(example.duplicateString_("Wagga"), "WaggaWagga")
Beispiel #41
0
 def test_block_property_pytypes(self):
     BlockPropertyExample = ObjCClass("BlockPropertyExample")
     instance = BlockPropertyExample.alloc().init()
     result = ObjCBlock(instance.blockProperty, int, int, int)(1, 2)
     self.assertEqual(result, 3)
Beispiel #42
0
 def test_double_method(self):
     "A method with a double argument can be handled."
     Example = ObjCClass('Example')
     example = Example.alloc().init()
     self.assertAlmostEqual(example.areaOfCircle_(1.5), 1.5 * math.pi, 5)