2
// Test the generated API selectors against typos or non-existing cases
5
// Sebastien Pouliot <sebastien@xamarin.com>
7
// Copyright 2012-2013 Xamarin Inc.
9
// Licensed under the Apache License, Version 2.0 (the "License");
10
// you may not use this file except in compliance with the License.
11
// You may obtain a copy of the License at
13
// http://www.apache.org/licenses/LICENSE-2.0
15
// Unless required by applicable law or agreed to in writing, software
16
// distributed under the License is distributed on an "AS IS" BASIS,
17
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
// See the License for the specific language governing permissions and
19
// limitations under the License.
23
using System.Reflection;
24
using NUnit.Framework;
27
using MonoMac.Foundation;
28
using MonoMac.ObjCRuntime;
30
using MonoTouch.Foundation;
31
using MonoTouch.ObjCRuntime;
34
namespace TouchUnit.Bindings {
36
public abstract class ApiSelectorTest : ApiBaseTest {
40
// not everything should be even tried
42
protected virtual bool Skip (Type type)
44
// skip delegate (and other protocol references)
45
foreach (object ca in type.GetCustomAttributes (false)) {
46
if (ca is ModelAttribute)
52
protected virtual bool Skip (Type type, string selectorName)
57
protected virtual bool CheckResponse (bool value, Type actualType, Type declaredType, ref string name)
62
name = actualType.FullName + " : " + name;
67
public void InstanceMethods ()
71
IntPtr responds_handle = Selector.GetHandle ("instancesRespondToSelector:");
73
foreach (Type t in Assembly.GetTypes ()) {
74
if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
77
if (Skip (t) || SkipDueToAttribute (t))
80
FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
82
continue; // e.g. *Delegate
83
IntPtr class_ptr = (IntPtr) fi.GetValue (null);
85
foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
87
if (m.DeclaringType != t || SkipDueToAttribute (m))
90
foreach (object ca in m.GetCustomAttributes (true)) {
91
ExportAttribute export = (ca as ExportAttribute);
95
string name = export.Selector;
99
bool result = Messaging.bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name));
100
bool response = CheckResponse (result, t, m.DeclaringType, ref name);
101
if (!ContinueOnFailure)
102
Assert.IsTrue (response, name);
103
else if (!response) {
104
CheckResponse (result, t, m.DeclaringType, ref name);
105
Console.WriteLine ("[FAIL] {0}", name);
112
Assert.AreEqual (0, Errors, "{0} errors found in {1} instance selector validated", Errors, n);
115
protected virtual void Dispose (NSObject obj, Type type)
120
// funny, this is how I envisioned the instance version... before hitting run :|
121
protected virtual bool CheckStaticResponse (bool value, Type actualType, Type declaredType, ref string name)
126
name = actualType.FullName + " : " + name;
131
public void StaticMethods ()
136
IntPtr responds_handle = Selector.GetHandle ("respondsToSelector:");
138
foreach (Type t in Assembly.GetTypes ()) {
139
if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
142
if (Skip (t) || SkipDueToAttribute (t))
145
FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
147
continue; // e.g. *Delegate
148
IntPtr class_ptr = (IntPtr) fi.GetValue (null);
150
foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)) {
151
if (SkipDueToAttribute (m))
154
foreach (object ca in m.GetCustomAttributes (true)) {
155
if (ca is ExportAttribute) {
156
string name = (ca as ExportAttribute).Selector;
157
bool result = Messaging.bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name));
158
bool response = CheckStaticResponse (result, t, m.DeclaringType, ref name);
159
if (!ContinueOnFailure)
160
Assert.IsTrue (response, name);
161
else if (!response) {
162
Console.WriteLine ("[FAIL] {0}", name);
170
Assert.AreEqual (0, Errors, "{0} errors found in {1} static selector validated", Errors, n);
173
protected virtual bool HasNoSetter (PropertyInfo p)
179
public void MissingSetters ()
184
IntPtr responds_handle = Selector.GetHandle ("instancesRespondToSelector:");
186
foreach (Type t in Assembly.GetTypes ()) {
187
if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
195
FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
197
continue; // e.g. *Delegate
198
IntPtr class_ptr = (IntPtr) fi.GetValue (null);
200
foreach (var p in t.GetProperties (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) {
202
if (p.DeclaringType != t || SkipDueToAttribute (p))
205
var mg = p.GetGetMethod ();
206
var ms = p.GetSetMethod ();
207
if (HasNoSetter (p) || (mg == null) || (ms != null))
210
if (SkipDueToAttribute (mg) || SkipDueToAttribute (ms))
213
foreach (object ca in mg.GetCustomAttributes (true)) {
214
if (ca is ExportAttribute) {
215
// if getter has [Export] assume it's valid (there's a test for this)
216
string name = (ca as ExportAttribute).Selector;
217
if (!Messaging.bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name)))
221
string setter_selector = String.Format ("set{0}{1}:", Char.ToUpperInvariant (name [0]), name.Substring (1));
223
Console.WriteLine ("{0} {1} '{2} {3}' selector: {4}", n, t.Name, mg.IsStatic ? "static" : "instance", p, setter_selector);
225
bool result = !Messaging.bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (setter_selector));
226
if (!ContinueOnFailure)
227
Assert.IsTrue (result, t.Name + " - " + setter_selector);
229
Console.WriteLine ("[FAIL] {0} {1}", t, setter_selector);
236
Assert.AreEqual (0, Errors, "{0} potential errors found in {1} setters validated", Errors, n);