Commits

Ronald Oussoren  committed d84ad98

Add some more tests for method resolution

  • Participants
  • Parent commits f254281

Comments (0)

Files changed (4)

File pyobjc-core/Modules/objc/test/methres1.m

+#include "Python.h"
+#include "pyobjc-api.h"
+
+#import <Foundation/Foundation.h>
+
+@interface NSObject (MethodResolution1)
+{
+}
+-(id)oc_method1;
+-(id)ocmethod2;
+@end
+
+@implementation NSObject (MethodResolution1)
+
+-(id)oc_method1
+{
+	return @"NSObject.oc_method1";
+}
+
+-(id)ocmethod2
+{
+	return @"NSObject.ocmethod2";
+}
+
+@end
+
+
+static PyMethodDef mod_methods[] = {
+    { 0, 0, 0, 0 }
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+
+static struct PyModuleDef mod_module = {
+    PyModuleDef_HEAD_INIT,
+    "methres1",
+    NULL,
+    0,
+    mod_methods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+#define INITERROR() return NULL
+#define INITDONE() return m
+
+PyObject* PyInit_methres1(void);
+
+PyObject* __attribute__((__visibility__("default")))
+PyInit_methres1(void)
+
+#else
+
+#define INITERROR() return
+#define INITDONE() return
+
+void initmethres1(void);
+
+void __attribute__((__visibility__("default")))
+initinitialize(void)
+#endif
+{
+    PyObject* m;
+
+#if PY_VERSION_HEX >= 0x03000000
+    m = PyModule_Create(&mod_module);
+#else
+    m = Py_InitModule4("methres1", mod_methods,
+        NULL, NULL, PYTHON_API_VERSION);
+#endif
+    if (!m) {
+        INITERROR();
+    }
+
+    INITDONE();
+}

File pyobjc-core/Modules/objc/test/methres2.m

+#include "Python.h"
+#include "pyobjc-api.h"
+
+#import <Foundation/Foundation.h>
+
+@interface NSURL (MethodResolution2)
+{
+}
+-(id)oc_method1;
+-(id)ocmethod2;
+@end
+
+@implementation NSURL (MethodResolution2)
+
+-(id)oc_method1
+{
+	return @"NSURL.oc_method1";
+}
+
+-(id)ocmethod2
+{
+	return @"NSURL.ocmethod2";
+}
+
+@end
+
+
+static PyMethodDef mod_methods[] = {
+    { 0, 0, 0, 0 }
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+
+static struct PyModuleDef mod_module = {
+    PyModuleDef_HEAD_INIT,
+    "methres2",
+    NULL,
+    0,
+    mod_methods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+#define INITERROR() return NULL
+#define INITDONE() return m
+
+PyObject* PyInit_methres2(void);
+
+PyObject* __attribute__((__visibility__("default")))
+PyInit_methres2(void)
+
+#else
+
+#define INITERROR() return
+#define INITDONE() return
+
+void initmethres2(void);
+
+void __attribute__((__visibility__("default")))
+initinitialize(void)
+#endif
+{
+    PyObject* m;
+
+#if PY_VERSION_HEX >= 0x03000000
+    m = PyModule_Create(&mod_module);
+#else
+    m = Py_InitModule4("methres2", mod_methods,
+        NULL, NULL, PYTHON_API_VERSION);
+#endif
+    if (!m) {
+        INITERROR();
+    }
+
+    INITDONE();
+}

File pyobjc-core/PyObjCTest/test_methres.py

+from PyObjCTools.TestSupport import *
+
+import objc
+
+NSObject = objc.lookUpClass('NSObject')
+NSURL = objc.lookUpClass('NSURL')
+
+class TestMethodResolution (TestCase):
+    def test_loading_categories(self):
+        obj = NSObject.alloc().init()
+        url = NSURL.alloc().initWithString_("http://www.python.org/")
+        self.assertIsInstance(obj, NSObject)
+        self.assertIsInstance(url, NSObject)
+        self.assertIsInstance(url, NSURL)
+
+        self.assertRaises(AttributeError, getattr, obj, 'oc_method1')
+        self.assertRaises(AttributeError, getattr, obj, 'ocmethod2')
+
+        # Check that a category was added to NSObject, and that
+        # it can be used for NSURL objects as well.
+        # NOTE: Don't check resolution of NSURL.ocmethod2 to ensure
+        #       that resolution even works when there'd be a cache.
+        import PyObjCTest.methres1
+        self.assertEqual(obj.oc_method1(), 'NSObject.oc_method1')
+        self.assertEqual(obj.ocmethod2(), 'NSObject.ocmethod2')
+        self.assertEqual(url.oc_method1(), 'NSObject.oc_method1')
+        #self.assertEqual(url.ocmethod2(), 'NSObject.ocmethod2')
+        self.assertEqual(super(NSURL, url).oc_method1(), 'NSObject.oc_method1')
+        #self.assertEqual(super(NSURL, url).ocmethod2(), 'NSObject.ocmethod2')
+
+        # Load an NSURL category and check that it is used.
+        import PyObjCTest.methres2
+        self.assertEqual(obj.oc_method1(), 'NSObject.oc_method1')
+        self.assertEqual(obj.ocmethod2(), 'NSObject.ocmethod2')
+        self.assertEqual(url.oc_method1(), 'NSURL.oc_method1')
+        self.assertEqual(url.ocmethod2(), 'NSURL.ocmethod2')
+        self.assertEqual(super(NSURL, url).oc_method1(), 'NSObject.oc_method1')
+        self.assertEqual(super(NSURL, url).ocmethod2(), 'NSObject.ocmethod2')
+
+
+if __name__ == "__main__":
+    main()

File pyobjc-core/TODO.txt

 Short term
 ----------
 
-* Better tests for the new C code, especially:
-
-  - lookup of selectors like 'prefix_suffixCanDo:withObject:' (with an embedded underscore)
-    test if a subclass version is found when the superclass version is already in __dict__.
-
-  - test_methodlookup might not yet test all relevant code paths
-
 * Code cleanup for the new C code, I've done too much copy&paste editing
   while getting the new code to work properly.
 
 
 * Look for a more efficient encoding of _metadata.py, possibly using a C exension
 
-* Look for a more efficient encoding of method metadata registry (the data
-  structure maintained by ``objc.registerMetaDataForSelector``)
-
 * Try adding support for ARC runtime functions (to avoid hitting
   the autorelease pool on systems using ARC)
 
   That is, some strins don't archive properly? Work around this in
   OC_PythonUnicode's archiving support
 
-* Add _named_int, _named_long, _named_float to lazy loader to get nicer
-  repr/str for named constants.
-
-  Problem: non-empty slots is not supported for type long
-
-* Crash with -fcatch-undefined-behavior (see setup.py)
-
 * Finish partial bindings:
   - AVFoundation
   - GameKit
 * Improve documentation, both end-user documentation and documentation
   on how the bridge works.
 
-* Add some more tests for method resolution:
-
-  - Add methods after object is first used from python:
-
-    1. a completely new method
-
-    2. a method that overrides a method from the superclass
-
-    In both cases check that the method can be called (both directly
-    and through super)
-
-
 * JavsaScriptCore bindings need work (missing opaque pointer types, no tests, no examples, ...)
 
-* Add tests for objc.ObjCPointer (creating, introspection, accessing value, accessing pointer)
-
 * Add (private) function to convert dictionary to a compiled metadata object,
   use that to reduce the memory use of the 'lazy' modules used by metadata
   (either by generating calls in the metadata converted or converting manually in the
-  laze module)
+  lazy module)
 
 * Further speedups in method calls: I've already reduced the amount of
   memory allocations (PyMem_Alloc, ...), and it should be possible to