diff --git a/tests/bindings/ApiBaseTest.cs b/tests/bindings/ApiBaseTest.cs index edcf9d42..5084a384 100644 --- a/tests/bindings/ApiBaseTest.cs +++ b/tests/bindings/ApiBaseTest.cs @@ -21,6 +21,7 @@ using System; using System.Reflection; +using System.Runtime.InteropServices; #if MONOMAC using MonoMac.Foundation; @@ -32,6 +33,20 @@ namespace TouchUnit.Bindings { public abstract class ApiBaseTest { + [DllImport ("/usr/lib/libobjc.dylib")] + // note: the returned string is not ours to free + protected static extern IntPtr objc_getClass (string name); + + [DllImport ("/usr/lib/libobjc.dylib")] + // note: the returned string is not ours to free + protected static extern IntPtr method_getTypeEncoding (IntPtr method); + + [DllImport ("/usr/lib/libobjc.dylib")] + protected static extern IntPtr class_getClassMethod (IntPtr klass, IntPtr selector); + + [DllImport ("/usr/lib/libobjc.dylib")] + protected static extern IntPtr class_getInstanceMethod (IntPtr klass, IntPtr selector); + /// /// Gets or sets a value indicating whether this test fixture will continue after failures. /// diff --git a/tests/bindings/ApiSelectorTest.cs b/tests/bindings/ApiSelectorTest.cs index 0681e6a5..26d2097b 100644 --- a/tests/bindings/ApiSelectorTest.cs +++ b/tests/bindings/ApiSelectorTest.cs @@ -21,6 +21,7 @@ using System; using System.Reflection; +using System.Runtime.InteropServices; using NUnit.Framework; #if MONOMAC @@ -82,34 +83,53 @@ public void InstanceMethods () continue; // e.g. *Delegate IntPtr class_ptr = (IntPtr) fi.GetValue (null); - foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { - - if (m.DeclaringType != t || SkipDueToAttribute (m)) - continue; + foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) + CheckSelector (m, t, class_ptr, responds_handle, ref n); + foreach (var m in t.GetConstructors (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) + CheckSelector (m, t, class_ptr, responds_handle, ref n); - foreach (object ca in m.GetCustomAttributes (true)) { - ExportAttribute export = (ca as ExportAttribute); - if (export == null) - continue; - - string name = export.Selector; - if (Skip (t, name)) - continue; - - bool result = Messaging.bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name)); - bool response = CheckResponse (result, t, m.DeclaringType, ref name); - if (!ContinueOnFailure) - Assert.IsTrue (response, name); - else if (!response) { - CheckResponse (result, t, m.DeclaringType, ref name); - Console.WriteLine ("[FAIL] {0}", name); - Errors++; - } - n++; - } - } } Assert.AreEqual (0, Errors, "{0} errors found in {1} instance selector validated", Errors, n); + Console.WriteLine (n); + } + + void CheckSelector (MethodBase m, Type t, IntPtr class_ptr, IntPtr responds_handle, ref int n) + { + if (m.DeclaringType != t || SkipDueToAttribute (m)) + return; + + foreach (object ca in m.GetCustomAttributes (true)) { + ExportAttribute export = (ca as ExportAttribute); + if (export == null) + continue; + + string name = export.Selector; + if (Skip (t, name)) + continue; + + IntPtr sel = Selector.GetHandle (name); + IntPtr method = class_getInstanceMethod (class_ptr, sel); + IntPtr tenc = method_getTypeEncoding (method); + string encoded = Marshal.PtrToStringAuto (tenc); + + if (LogProgress) + Console.WriteLine ("{0} {1} '{2} {3}' selector: {4} == {5}", n, t.Name, m is ConstructorInfo ? "ctor" : "instance", m, name, encoded); + + // NSObject has quite a bit of stuff that's not usable (except by some class that inherits from it) + if (String.IsNullOrEmpty (encoded)) + continue; + + bool result = Messaging.bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name)); + bool response = CheckResponse (result, t, m.DeclaringType, ref name); + if (!ContinueOnFailure) + Assert.IsTrue (response, name); + else if (!response) { + CheckResponse (result, t, m.DeclaringType, ref name); + Console.WriteLine ("[FAIL] {0}", name); + Errors++; + } + n++; + } } protected virtual void Dispose (NSObject obj, Type type) diff --git a/tests/bindings/ApiSignatureTest.cs b/tests/bindings/ApiSignatureTest.cs index 460d3fdd..9705a214 100644 --- a/tests/bindings/ApiSignatureTest.cs +++ b/tests/bindings/ApiSignatureTest.cs @@ -38,20 +38,6 @@ namespace TouchUnit.Bindings { public abstract class ApiSignatureTest : ApiBaseTest { - [DllImport ("/usr/lib/libobjc.dylib")] - // note: the returned string is not ours to free - static extern IntPtr objc_getClass (string name); - - [DllImport ("/usr/lib/libobjc.dylib")] - // note: the returned string is not ours to free - static extern IntPtr method_getTypeEncoding (IntPtr method); - - [DllImport ("/usr/lib/libobjc.dylib")] - static extern IntPtr class_getClassMethod (IntPtr klass, IntPtr selector); - - [DllImport ("/usr/lib/libobjc.dylib")] - static extern IntPtr class_getInstanceMethod (IntPtr klass, IntPtr selector); - protected int Errors; protected string[] Split (string encoded, out int size)