]> git.saurik.com Git - apple/objc4.git/blobdiff - test/exchangeImp.m
objc4-437.tar.gz
[apple/objc4.git] / test / exchangeImp.m
diff --git a/test/exchangeImp.m b/test/exchangeImp.m
new file mode 100644 (file)
index 0000000..8649e73
--- /dev/null
@@ -0,0 +1,86 @@
+#include "test.h"
+#include <objc/objc-runtime.h>
+
+static int state;
+
+#define ONE 1
+#define TWO 2
+#define LENGTH 3
+#define COUNT 4
+
+@interface Super { id isa; } @end
+@implementation Super
++class { return self; }
++(void)initialize { } 
++(void) one { state = ONE; }
++(void) two { state = TWO; }
++(void) length { state = LENGTH; }
++(void) count { state = COUNT; }
+@end
+
+#define checkExchange(s1, v1, s2, v2)                                   \
+    do {                                                                \
+        Method m1, m2;                                                  \
+                                                                        \
+        /* Check unexchanged version */                                 \
+        state = 0;                                                      \
+        [Super s1];                                                     \
+        testassert(state == v1);                                        \
+        state = 0;                                                      \
+        [Super s2];                                                     \
+        testassert(state == v2);                                        \
+                                                                        \
+        /* Exchange */                                                  \
+        m1 = class_getClassMethod([Super class], @selector(s1));        \
+        m2 = class_getClassMethod([Super class], @selector(s2));        \
+        testassert(m1);                                                 \
+        testassert(m2);                                                 \
+        method_exchangeImplementations(m1, m2);                         \
+                                                                        \
+        /* Check exchanged version */                                   \
+        state = 0;                                                      \
+        [Super s1];                                                     \
+        testassert(state == v2);                                        \
+        state = 0;                                                      \
+        [Super s2];                                                     \
+        testassert(state == v1);                                        \
+                                                                        \
+        /* NULL should do nothing */                                    \
+        method_exchangeImplementations(m1, NULL);                       \
+        method_exchangeImplementations(NULL, m2);                       \
+        method_exchangeImplementations(NULL, NULL);                     \
+                                                                        \
+        /* Make sure NULL did nothing */                                \
+        state = 0;                                                      \
+        [Super s1];                                                     \
+        testassert(state == v2);                                        \
+        state = 0;                                                      \
+        [Super s2];                                                     \
+        testassert(state == v1);                                        \
+                                                                        \
+        /* Put them back */                                             \
+        method_exchangeImplementations(m1, m2);                         \
+                                                                        \
+        /* Check restored version */                                    \
+        state = 0;                                                      \
+        [Super s1];                                                     \
+        testassert(state == v1);                                        \
+        state = 0;                                                      \
+        [Super s2];                                                     \
+        testassert(state == v2);                                        \
+    } while (0) 
+
+int main()
+{
+    // Check ordinary selectors
+    checkExchange(one, ONE, two, TWO);
+
+    // Check vtable selectors
+    checkExchange(length, LENGTH, count, COUNT);
+
+    // Check ordinary<->vtable and vtable<->ordinary
+    checkExchange(count, COUNT, one, ONE);
+    checkExchange(two, TWO, length, LENGTH);
+
+    succeed(__FILE__);
+}