diff --git a/tests/.gitignore b/tests/.gitignore
index 323d1973fafa..aa989f0701ba 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,4 +1,26 @@
-*-tvos.csproj
-*-watchos.csproj
-*-unified.csproj
+index.html
+*.log
+*-unified.sln
+TestResult.xml
+build
+*-tvos.?sproj
+*-tvos.sln
+*-watchos.?sproj
+*-watchos-app.?sproj
+*-watchos-extension.?sproj
+*-watchos.sln
+*-tvos.plist
+*-watchos.plist
+*-unified.?sproj
+*-unifiedXM45.?sproj
+*-unifiedXM45.sln
+Makefile-mac.inc
+.stamp*
+Info-*.plist
+*.zip
+Makefile.inc
+*.stamp
+test.config
+mac-test-package
+.nuget
diff --git a/tests/BundledResources/BundledResources.csproj b/tests/BundledResources/BundledResources.csproj
new file mode 100644
index 000000000000..18d9fd56b62c
--- /dev/null
+++ b/tests/BundledResources/BundledResources.csproj
@@ -0,0 +1,54 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ BundledResources
+ Resources
+ BundledResources
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ False
+
+
+ none
+ True
+ bin\Release
+ prompt
+ 4
+ False
+ DO_NOT_REMOVE
+
+
+
+
+
+
+
+
+
+
+ basn3p08.png
+
+
+ xamvideotest.mp4
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/BundledResources/ResourcesTest.cs b/tests/BundledResources/ResourcesTest.cs
new file mode 100644
index 000000000000..5bd5d98fd27a
--- /dev/null
+++ b/tests/BundledResources/ResourcesTest.cs
@@ -0,0 +1,49 @@
+//
+// Resource Bundling Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.IO;
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace BundledResources {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class ResourcesTest {
+
+ [Test]
+ public void Bundled ()
+ {
+ // files are extracted (by MonoDevelop) so we can see them in the file system
+ // that's true for simulator or devices and whatever the linker settings are
+ var dir = NSBundle.MainBundle.BundlePath;
+ Assert.True (File.Exists (Path.Combine (dir, "basn3p08.png")), "file-basn3p08.png");
+ Assert.True (File.Exists (Path.Combine (dir, "xamvideotest.mp4")), "xamvideotest.mp4");
+
+ // resources are removed by the linker or an extra step (e.g. "link sdk" or "don't link") but that
+ // extra step is done only on device (to keep the simulator builds as fast as possible)
+ var resources = typeof(ResourcesTest).Assembly.GetManifestResourceNames ();
+ if (Runtime.Arch == Arch.DEVICE) {
+ Assert.That (resources.Length, Is.EqualTo (0), "No resources");
+ } else {
+ Assert.That (resources.Length, Is.GreaterThanOrEqualTo (2), "Resources");
+ Assert.That (resources, Contains.Item ("__monotouch_content_basn3p08.png"), "res-basn3p08.png");
+ Assert.That (resources, Contains.Item ("__monotouch_content_xamvideotest.mp4"), "res-xamvideotest.mp4");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/EmbeddedResources/EmbeddedResources.csproj b/tests/EmbeddedResources/EmbeddedResources.csproj
new file mode 100644
index 000000000000..4e737dfe798a
--- /dev/null
+++ b/tests/EmbeddedResources/EmbeddedResources.csproj
@@ -0,0 +1,53 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {676F527D-3352-42EA-9DE2-181C45003568}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ EmbeddedResources
+ Resources
+ EmbeddedResources
+ true
+ ..\..\..\xamarin-macios\product.snk
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ False
+
+
+ none
+ True
+ bin\Release
+ prompt
+ 4
+ False
+ DO_NOT_REMOVE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/EmbeddedResources/ResourcesTest.cs b/tests/EmbeddedResources/ResourcesTest.cs
new file mode 100644
index 000000000000..df3728d192c4
--- /dev/null
+++ b/tests/EmbeddedResources/ResourcesTest.cs
@@ -0,0 +1,40 @@
+//
+// Resource Bundling Tests
+//
+// Authors:
+// Rolf Bjarne Kvinge (rolf@xamarin.com)
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.IO;
+using System.Resources;
+using System.Globalization;
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace EmbeddedResources {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class ResourcesTest {
+
+ [Test]
+ public void Embedded ()
+ {
+ var manager = new ResourceManager ("EmbeddedResources.Welcome", typeof(ResourcesTest).Assembly);
+
+ Assert.AreEqual ("Welcome", manager.GetString ("String1", new CultureInfo ("en")), "en");
+ Assert.AreEqual ("Willkommen", manager.GetString ("String1", new CultureInfo ("de")), "de");
+ Assert.AreEqual ("Bienvenido", manager.GetString ("String1", new CultureInfo ("es")), "es");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/EmbeddedResources/Welcome.de.resx b/tests/EmbeddedResources/Welcome.de.resx
new file mode 100755
index 000000000000..73b49728033d
--- /dev/null
+++ b/tests/EmbeddedResources/Welcome.de.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Willkommen
+
+
\ No newline at end of file
diff --git a/tests/EmbeddedResources/Welcome.es.resx b/tests/EmbeddedResources/Welcome.es.resx
new file mode 100755
index 000000000000..4adb75c3c1f6
--- /dev/null
+++ b/tests/EmbeddedResources/Welcome.es.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Bienvenido
+
+
\ No newline at end of file
diff --git a/tests/EmbeddedResources/Welcome.resx b/tests/EmbeddedResources/Welcome.resx
new file mode 100755
index 000000000000..b1b776a53a30
--- /dev/null
+++ b/tests/EmbeddedResources/Welcome.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Welcome
+
+
\ No newline at end of file
diff --git a/tests/Makefile b/tests/Makefile
index c934fc6de10c..d7b0849d3269 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,5 +1,342 @@
-TOP=..
+TOP = ../../xamarin-macios
+
+ifdef INCLUDE_MAC
+SUBDIRS += no-mmp
+endif
+# disabled for now: mac-test
+
include $(TOP)/Make.config
+include $(TOP)/mk/rules.mk
+
+MTOUCH=$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/bin/mtouch
+UNIT_SERVER_DIR=$(TOUCH_UNIT_PATH)/Touch.Server
+UNIT_SERVER=$(UNIT_SERVER_DIR)/bin/Debug/Touch.Server.exe
+TEST_SUITES=monotouch-test link\ sdk link\ all dont\ link framework-test mini
+BCL_TEST_SUITES=mscorlib System System.Core System.Data System.Net.Http System.Numerics System.Runtime.Serialization System.Transactions System.Web.Services System.Xml System.Xml.Linq Mono.Security System.ComponentModel.DataAnnotations System.Json System.ServiceModel.Web Mono.Data.Sqlite
+ALL_TEST_SUITES=$(TEST_SUITES) $(BCL_TEST_SUITES)
+EXEC_UNIT_SERVER=XCODE_DEVELOPER_ROOT=$(XCODE_DEVELOPER_ROOT) MONOTOUCH_ROOT=$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX) $(SYSTEM_MONO) --debug $(UNIT_SERVER)
+
+export MD_APPLE_SDK_ROOT=$(abspath $(XCODE_DEVELOPER_ROOT)/../..)
+export MD_MTOUCH_SDK_ROOT=$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)
+export XBUILD_FRAMEWORK_FOLDERS_PATH=$(IOS_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild-frameworks
+export MSBuildExtensionsPath=$(IOS_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild
+export XAMMAC_FRAMEWORK_PATH=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current
+export XamarinMacFrameworkRoot=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current
+
+ifneq ($(RELEASE),)
+CONFIG=Release
+else
+CONFIG=Debug
+endif
+
+ifeq ($(V),)
+ifeq ($(BUILD_REVISION),)
+# non-verbose local build
+XHARNESS_VERBOSITY=
+else
+# wrench build
+XHARNESS_VERBOSITY=--verbose
+endif
+else
+# verbose build
+XHARNESS_VERBOSITY=--verbose
+endif
+
+#
+# To run all the tests, just do:
+#
+# make run-tests
+#
+# and go take a long tea break.
+#
+# For faster turnaround there are specific targets that can be used
+# to run specific test suites. For more information read the README.md.
+#
+
+all-local:: qa-test-dependencies.zip mac-test-package.zip
+
+test.config: Makefile $(TOP)/Make.config
+ @rm -f $@
+ @echo "MONOTOUCH_PREFIX=$(abspath $(MONOTOUCH_PREFIX))" >> $@
+ @echo "IOS_DESTDIR=$(abspath $(IOS_DESTDIR))" >> $@
+ @echo "MAC_DESTDIR=$(abspath $(MAC_DESTDIR))" >> $@
+ @echo "WATCH_MONO_PATH=$(abspath $(WATCH_MONO_PATH))" >> $@
+
+clean-local::
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhoneSimulator /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhone /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhoneSimulator /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests-unified.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhone /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests-unified.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhoneSimulator /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests-tvos.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhoneSimulator /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests-tvos.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhone /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests-watchos.sln
+ $(Q) $(SYSTEM_XBUILD) /t:Clean /p:Platform=iPhone /p:Configuration=$(CONFIG) $(XBUILD_VERBOSITY) tests-watchos.sln
+
+## run targets = build + [install] + exec
+
+run run-all run-tests run-test:
+ $(Q) for subdir in $(SUBDIRS); do \
+ $(MAKE) -C $$subdir run || exit 1; \
+ done
+ $(Q) $(MAKE) run-local
+
+# separate build-dev-* entries because some of them are build with debug other (llvm) with release
+build-dev-bots: build-test-libraries
+ # test LLVM armv6, this is Classic only because arm64 doesn't have llvm support.
+ $(MAKE) "build-ios-devclassic-dont link" CONFIG=Release
+ # test LLVM armv7, this is Classic only because arm64 doesn't have llvm support.
+ $(MAKE) "build-ios-devclassic-link all" CONFIG=Release
+ # test LLVM armv6 arm7 (fat), this is Classic only because arm64 doesn't have llvm support.
+ $(MAKE) "build-ios-devclassic-link sdk" CONFIG=Release
+ # test LLVM arm7 w/thumb2, this is Classic only because arm64 doesn't have llvm support.
+ $(MAKE) build-ios-devclassic-monotouch-test CONFIG=Release
+ # test BCL mscorlib
+ $(MAKE) build-ios-dev-mscorlib CONFIG=Release
+ # test BCL System.Core
+ $(MAKE) build-ios-dev-System.Core CONFIG=Release
+ # run any other scripted tests
+ $(MAKE) -C scripted
+
+build-% run-% exec-% install-%:
+ @echo ""
+ @echo "\033[0;31mUnknown target: $@\033[0m"
+ @echo ""
+ @echo "Syntax is: ---"
+ @echo " Action: build, install (only for device), exec, run (= build + install + exec)."
+ @echo " Platform: ios, tvos, watchos (can be skipped, in which case all platforms are executed)"
+ @echo " Where: "
+ @echo " ios: sim = [simclassic + simunified = [sim32, sim64]]; dev = [devclassic + devunified]"
+ @echo " tvos/watchos: sim, dev"
+ @echo " What: The test project to run (BCL tests do not need to be treated specially anymore, just use test project's name)"
+ @echo ""
+ @echo "Example:"
+ @echo ""
+ @echo " # this will run monotouch-test on an Apple TV device"
+ @echo " $ make run-tvos-dev-monotouch-test"
+ @echo ""
+ @echo "For more info read README.md."
+ @echo ""
+ @exit 1
+
+check-result:
+ @test -z "$(BUILD_REVISION)" || echo "@MonkeyWrench: AddFile: $(abspath $(FILE))"
+ @if grep "Tests run" "$(FILE)"; then \
+ if grep FAIL "$(FILE)"; then \
+ test "x" == "x$(BUILD_REVISION)" -o "x" == "x$(TESTNAME)" || echo "@MonkeyWrench: AddSummary: $(TESTNAME) failed: `grep "Tests run:" "$(FILE)" | sed 's/Tests run: //'`
"; \
+ echo Test run failed; \
+ exit 1; \
+ else \
+ test "x" == "x$(BUILD_REVISION)" -o "x" == "x$(TESTNAME)" || echo "@MonkeyWrench: AddSummary: $(TESTNAME) succeeded: `grep "Tests run:" "$(FILE)" | sed 's/Tests run: //'`
"; \
+ echo Test run succeeded; \
+ fi; \
+ else \
+ test "x" == "x$(BUILD_REVISION)" -o "x" == "x$(TESTNAME)" || echo "@MonkeyWrench: AddSummary: $(TESTNAME) crashed
"; \
+ echo Test run crashed; \
+ exit 1; \
+ fi
+
+logdev:
+ $(MTOUCH) --logdev
+
+$(UNIT_SERVER): $(wildcard $(UNIT_SERVER_DIR)/*.cs)
+ (cd $(UNIT_SERVER_DIR) && $(SYSTEM_XBUILD))
+
+build-test-libraries:
+ @$(MAKE) -C $(TOP)/tests/test-libraries
+
+Makefile.inc: xharness/xharness.exe
+ $(Q_GEN) $(SYSTEM_MONO) --debug $< $(XHARNESS_VERBOSITY) --configure --autoconf --rootdir $(CURDIR)
+
+-include Makefile.inc
+
+$(GUI_UNIT_PATH)/bin/net_4_5/GuiUnit.exe:
+ XBUILD_FRAMEWORK_FOLDERS_PATH=$(MAC_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild-frameworks MSBuildExtensionsPath=$(MAC_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild XamarinMacFrameworkRoot=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current xbuild $(GUI_UNIT_PATH)/src/framework/GuiUnit_NET_4_5.csproj
+
+$(GUI_UNIT_PATH)/bin/xammac_mobile/GuiUnit.exe:
+ XBUILD_FRAMEWORK_FOLDERS_PATH=$(MAC_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild-frameworks MSBuildExtensionsPath=$(MAC_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild XamarinMacFrameworkRoot=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current xbuild $(GUI_UNIT_PATH)/src/framework/GuiUnit_xammac_mobile.csproj
+
+Makefile-mac.inc: xharness/xharness.exe
+ $(Q_GEN) $(SYSTEM_MONO) --debug $< $(XHARNESS_VERBOSITY) --configure --autoconf --mac --rootdir $(CURDIR)
+
+-include Makefile-mac.inc
+
+$(TOP)/tools/mtouch/SdkVersions.cs: $(TOP)/tools/mtouch/SdkVersions.cs.in
+ @$(MAKE) -C $(TOP)/tools/mtouch SdkVersions.cs
+
+.stamp-src-project-files:
+ @$(MAKE) -C $(TOP)/src project-files
+ @touch $@
+
+xharness/xharness.exe: $(wildcard xharness/*.cs) xharness/xharness.csproj $(TOP)/tools/mtouch/SdkVersions.cs test.config .stamp-src-project-files
+ $(Q_GEN) $(SYSTEM_XBUILD) $(XBUILD_VERBOSITY_QUIET) xharness/xharness.csproj
+
+killall:
+ @killall "iPhone Simulator" >/dev/null 2>&1 || true
+ @killall "iOS Simulator" >/dev/null 2>&1 || true
+ @killall Touch.Server >/dev/null 2>&1 || true
+
+NUNIT_MSBUILD_DIR=$(TOP)/msbuild/packages/NUnit.Runners.2.6.4/tools/lib
+test-ios-tasks:
+ $(SYSTEM_XBUILD) $(TOP)/msbuild/Xamarin.MacDev.Tasks.sln
+ cd $(NUNIT_MSBUILD_DIR) && $(SYSTEM_MONO) ../nunit-console.exe ../../../../tests/bin/Xamarin.iOS.Tasks.Tests.dll -xml=TestResults_Xamarin.iOS.Tasks.Tests.xml -labels $(TEST_FIXTURE) || touch .failed-stamp
+ @[[ -z "$$BUILD_REPOSITORY" ]] || ( xsltproc $(TOP)/tests/HtmlTransform.xslt $(NUNIT_MSBUILD_DIR)/TestResults_Xamarin.iOS.Tasks.Tests.xml > $(TOP)/tests/index.html && echo "@MonkeyWrench: AddFile: $$PWD/index.html" )
+ @if test -e $(NUNIT_MSBUILD_DIR)/.failed-stamp; then rm $(NUNIT_MSBUILD_DIR)/.failed-stamp; exit 1; fi
+
+ifdef ENABLE_XAMARIN
+ifdef INCLUDE_IOS
+qa-test-dependencies.zip:
+ @$(MAKE) build-test-libraries
+ @# Make sure we start from a clean slate
+ $(Q) rm -rf $@ $@.tmpdir
+ifdef INCLUDE_TVOS
+ @# TVOS
+ $(Q) mkdir -p $@.tmpdir/tvos
+ $(Q) cp $(TOP)/src/build/tvos/reference/MonoTouch.Dialog-1.dll* $@.tmpdir/tvos
+ $(Q) cp $(TOP)/src/build/tvos/reference/MonoTouch.NUnitLite.dll* $@.tmpdir/tvos
+ $(Q) cp $(TOP)/tests/test-libraries/.libs/tvos/libtest.a $@.tmpdir/tvos
+ $(Q) cp $(TOP)/tests/test-libraries/.libs/tvos/libtest.dylib $@.tmpdir/tvos
+ $(Q) cp -a $(TOP)/tests/test-libraries/.libs/tvos/XTest.framework $@.tmpdir/tvos
+endif
+ @# iOS
+ $(Q) mkdir -p $@.tmpdir/ios
+ $(Q) cp $(TOP)/tests/test-libraries/.libs/ios/libtest.a $@.tmpdir/ios
+ $(Q) cp $(TOP)/tests/test-libraries/.libs/ios/libtest.dylib $@.tmpdir/ios
+ $(Q) cp -a $(TOP)/tests/test-libraries/.libs/ios/XTest.framework $@.tmpdir/ios
+ $(Q) cp $(MACCORE_PATH)/tools/mlaunch/mlaunch $@.tmpdir
+ @# Generate zip
+ $(Q_GEN) cd $@.tmpdir && zip -9r $(abspath $@) .
+ @# Cleanup
+ $(Q) rm -rf $@.tmpdir
+else
+qa-test-dependencies.zip:
+ @echo Not enabled
+endif
+else
+qa-test-dependencies.zip:
+ @echo Xamarin build not enabled
+endif
+
+ifdef INCLUDE_MAC
+mac-test-package.zip:
+ ./package-mac-tests.sh
+else
+mac-test-package.zip:
+ @echo Not enabled
+endif
+
+#XI
+ifdef INCLUDE_IOS
+wrench-mtouch:
+ cd mtouch && $(MAKE)
+ git clean -xfdq
+
+wrench-btouch:
+ cd generator && $(MAKE)
+ cd generator && git clean -xfdq
+
+wrench-build-unit-test-dev:
+ $(MAKE) build-dev-bots
+ git clean -xfdq
+
+wrench-sim-linksdk:
+ $(Q) $(MAKE) wrench-sim-link\ sdk
+
+wrench-sim-linkall:
+ $(Q) $(MAKE) wrench-sim-link\ all
+
+wrench-sim-dontlink:
+ $(Q) $(MAKE) wrench-sim-dont\ link
+
+else
+wrench-mtouch wrench-btouch wrench-build-unit-test-dev:
+ @echo "iOS tests have been disabled [$@]"
+endif
+
+## XM
+ifdef INCLUDE_MAC
+wrench-mac-dontlink:
+ $(Q) $(MAKE) run-mac-dontlink
+ $(Q) $(MAKE) clean-mac-dontlink
+
+wrench-mac-mmp:
+ @echo Now part of wrench-mac-mmptest
+
+wrench-mac-misc:
+ @echo Tests mac-misc tests removed
+
+wrench-mac-apidiff:
+ @echo This is done in the normal api-diff target now.
+
+wrench-mac-drm:
+ @echo "The DRM tests have all been removed."
+
+wrench-mac-api:
+ $(Q) $(MAKE) run-mac-apitest
+ $(Q) $(MAKE) clean-mac-apitest
+
+wrench-mac-mmptest:
+ $(Q) $(MAKE) run-mac-mmptest
+ $(Q) $(MAKE) clean-mac-mmptest
+ $(Q) $(MAKE) -C mmptest/regression
+
+wrench-mac-msbuild:
+ $(Q) $(MAKE) run-mac-msbuild
+ $(Q) $(MAKE) clean-mac-msbuild
+
+wrench-mac-binding-project:
+ cd mac-binding-project && $(MAKE)
+ cd mac-binding-project && git clean -xfdq
+
+else
+wrench-mac-%:
+ @echo "Mac tests have been disabled [$@]"
+endif
+
+wrench-msbuild:
+ $(MAKE) -C $(TOP)/msbuild test-xml
+ifdef INCLUDE_IOS
+ $(MAKE) test-ios-tasks
+else
+ @echo "iOS tests have been disabled [$@]"
+endif
+ cd $(TOP)/msbuild && git clean -xfdq
+
+wrench-docs:
+ifdef ENABLE_XAMARIN
+ifdef INCLUDE_IOS
+ $(MAKE) -C $(MACCORE_PATH) update-docs
+else
+ @echo "iOS tests have been disabled [$@]"
+endif
+else
+ @echo "Docs have been disabled [$@]"
+endif
+
+# the wrenchhelper-* targets are generated.
+wrench-sim-%:
+ git clean -xfdq
+ifdef INCLUDE_IOS
+ unset LD_LIBRARY_PATH && script -q /dev/null $(MAKE) "wrenchhelper-$*"
+else
+ @echo "iOS tests have been disabled [$@]"
+endif
+
+wrench-bcl-sim-%:
+ git clean -xfdq
+ifdef INCLUDE_IOS
+ unset LD_LIBRARY_PATH && script -q /dev/null $(MAKE) "wrenchhelper-$*"
+else
+ @echo "iOS tests have been disabled [$@]"
+endif
+
+wrench-%:
+ git clean -xfdq
+ifdef INCLUDE_IOS
+ touch "exec-$*.log"
+ echo "@MonkeyWrench: AddFile: $(PWD)/exec-$*.log"
+ unset LD_LIBRARY_PATH && script -q /dev/null $(MAKE) "run-$*"
+ echo "Test succeeded"
+else
+ @echo "iOS tests have been disabled [$@]"
+endif
-%:
- $(MAKE) -C $(MACCORE_PATH)/tests $@
diff --git a/tests/README.md b/tests/README.md
index 66cf824d879f..f83b5688c9ea 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -1,4 +1,181 @@
-README.md
+# Various tests to be executed prior to releases
+
+## Test solutions
+
+Many of the test solutions and test projects are generated, and will
+only be available after running `make` once.
+
+* tests.sln: This is the base test solution, which targets iOS using the Classic API. _Not_ generated.
+* tests-unified.sln: All the iOS test projects using the Unified API. Generated.
+* tests-tvos.sln: All the TVOS test projects. Generated.
+* tests-watchos.sln: All the WatchOS test projects. Generated.
+
+### Test solution/project generation
+
+The tool that generates the test solutions / projects is called xharness,
+and lives in the xharness subdirectory.
+
+## Types of Tests
+
+### Unit Tests
+
+Most of the projects are using NUnit[Lite] and looks like unit tests.
+They are meant to be executed on the target: simulator, devices, OSX.
+
+In reality most of them are regression tests - but that does not change
+the need to execute and continually expand them to cover new code.
+
+
+### Introspection Tests
+
+Introspection tests are executed on target (both simulator and device for
+iOS) or a specific version of OSX. The application proceed to analyze itself
+using:
+
+* `System.Reflection` for managed code; and
+* the ObjectiveC runtime library for native code
+
+and compare the results. E.g. if using .NET reflection it can see a binding
+for a `NSBundle` type then it should be able to find a native `NSBundle`
+type using the ObjC runtime functions. Otherwise an error is raised...
+
+Since the application analyze itself it must contains everything we wish
+to test. That's why the introspection tests are part of the `dontlink.app`
+application (for iOS) and the dontlink-mac project (for OSX).
+
+Pros
+
+* They always tell the truth, which can differ from documentation
+
+Cons
+
+* Incomplete - Not everything is encoded in the metadata / executable;
+* Too complete - Not every truth is good to be known (or published)
+
+
+### Extrospection Tests ###
+
+Extrospection tests takes data from some outside sources and see if our
+implementation match the information, e.g.
+
+* Header files from the SDK;
+* Rules, like Gendarme or FxCop;
+
+Since this is done externally there's no need to run them on the devices,
+simulator or even a specific version of OSX.
+
+Pro
+
+* There is more data available, e.g. information lost when compiling
+
+Con
+
+* The data might not represent the truth (errors, false positives...)
+
+
+
+# Test Suites
+
+## *-tests : where * is the assembly name, e.g. monotouch
+
+Use the project defaults for linking, i.e.
+
+* "Don't link" for simulator
+
+* "Link SDK assemblies only" for devices
+
+## dontlink
+
+* regression testing without using the linker
+
+* both simulator and devices are set to "Don't link"
+
+## linkall
+
+* regression testing using the linker on the all assemblies
+
+* "Link all assemblies" for both simulator/devices
+
+## linksdk
+
+* regression testing using the linker on the SDK assemblies
+
+* "Link SDK assemblies only" for both simulator/devices
+
+## bcl-test
+
+These are the Mono BCL test suite tweaked to run on the mobile profile.
+It reuse the files directly from mono's repository (linking, not copying).
+
+As other unit tests the configuration is set to mimick normal apps, e.g.
+
+* "Don't link" for simulator
+
+* "Link SDK assemblies only" for devices
+
+
+# Common make targets
+
+Run every test in both the simulator and on device, using both the compat and the new profile (for the simulator both in 32 and 64bit mode).
+
+ $ make run
+
+Run every test in the simulator, using both the compat and the new profile (both 32 and 64bit simulators).
+
+ $ make run-all-sim
+
+Run every test on device, using both the compat and the new profile
+
+ $ make run-all-dev
+
+# Detailed make targets
+
+* Main target
+
+ * run-*what*-*where*-*project*: Builds, installs (if applicable) and runs the specified test project on the specified platform. This is the most common target to use.
+ * build-*what*-*where*-*project*: Will build the specified test project for the specified platform and target.
+ * install-*what*-*where*-*project*: Will install the specified test project on a connected device. There's currently no way to select the device, so ensure you've only one connected (if many devices are connected, it's random which will used).
+ * exec-*what*-*where*-*project*: Will run the specified test project in the simulator or on a device.
+
+* What
+
+ * -ios-: iOS.
+ * -tvos-: TVOS.
+ * -watchos-: WatchOS
+
+ If "What" is skipped, all variations are executed sequentially.
+
+* Where
+
+ * -simclassic-: Simulator using the Classic API. Only applicable when platform is iOS.
+ * -simunified-: Simulator using Unified API. The build will contain both an i386 and an x86_64 binary. Only applicable to the build-* target, while the -sim32- and -sim64- are only applicable to the exec-* targets. Only applicable when the platform is iOS.
+ * -sim32-: 32bits iOS simulator using the Unified API. Not applicable to other platforms.
+ * -sim64-: 64bits iOS simulator using the Unified API. Not applicable to other platforms.
+ * -sim-:
+ * iOS: Both the -simclassic- and -simunified- versions.
+ * WatchOS/TVOS: The WatchOS/TVOS simulator.
+ * -devclassic-: Device using the Classic API. Only applicable when the platform is iOS.
+ * -devunified-: Device using the Unified API. The build will contain both an armv7 and an arm64 binary. It's not possible to select a 32/64bit version, you'll run what your device supports. Only applicable when the platform is iOS.
+ * -dev-:
+ * iOS: Both the -devclassic- and -devunified- versions.
+ * WatchOS/TVOS: A Watch or TV device.
+
+* Examples
+
+ $ make run-ios-sim32-monotouchtest: This will run `monotouch-test` using the Unified API in a 32-bit simulator.
+ $ make run-tvos-dev-dont\ link: This will run `dont link` on an Apple TV device.
+
+# Utility run-* targets
+
+These targets will build, install (if applicable) and run the specified project(s).
+
+* Simulator
+ * run-sim-*project*: Builds and runs the specified test project in the simulator in compat, 32 and 64bit mode.
+ * run-sim: Builds and runs all the non-bcl test projects in the simulator in compat, 32 and 64bit mode.
+
+* Device
+ * run-dev-*project*: Builds and runs the specified non-bcl test project on a device in compat and native mode (if it's 32 and 64bit depends on the device; 64bit devices will run in 64bit mode and the same for 32bit devices).
+ * run-devcompat: Run all the non-bcl test projects on device, in compat mode.
+ * run-devdual: Run all the non-bcl test projects on device, in native mode (if it's 32 and 64bit depends on the device; 64bit devices will run in 64bit mode and the same for 32bit devices).
+ * run-dev: Run all the non-bcl test projects on device, in both compat and native mode.
-Our test suites are presently being re-worked to work without external,
-non public, dependencies. They will be added here shortly.
diff --git a/tests/api-shared/CoreFoundation/CFNotificationCenterTest.cs b/tests/api-shared/CoreFoundation/CFNotificationCenterTest.cs
new file mode 100644
index 000000000000..c8c82ea15844
--- /dev/null
+++ b/tests/api-shared/CoreFoundation/CFNotificationCenterTest.cs
@@ -0,0 +1,91 @@
+//
+// Unit tests for CFNotificationCenter
+//
+// Authors:
+// Miguel de Icaza (miguel@xamarin.com)
+//
+// Copyright 2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Net;
+
+#if XAMCORE_2_0
+using Foundation;
+using CoreFoundation;
+#else
+#if MONOMAC
+using MonoMac.CoreFoundation;
+using MonoMac.Foundation;
+#else
+using MonoTouch.CoreFoundation;
+using MonoTouch.Foundation;
+#endif
+#endif
+using NUnit.Framework;
+
+namespace MonoTouchFixtures.CoreFoundation
+{
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class CFNotificationCenterTest
+ {
+ [Test]
+ public void TestObservers ()
+ {
+ var target = new NSObject ();
+ var d = CFNotificationCenter.Local;
+ int count = 0;
+ int count2 = 0;
+ CFNotificationObserverToken o2 = null;
+ var o1 = d.AddObserver ("hello", target, (x,dd)=>{
+ count++;
+// Console.WriteLine ("Here");
+
+ if (count == 1)
+ o2 = d.AddObserver ("hello", target, (y,ee)=> {
+// Console.WriteLine ("There");
+ count2++;
+ });
+ });
+ d.PostNotification ("hello", target, null, deliverImmediately:true);
+ Assert.AreEqual (1, count);
+ d.PostNotification ("hello", target, null, deliverImmediately:true);
+ Assert.AreEqual (2, count);
+ Assert.AreEqual (1, count2);
+
+ // Remove the first observer, count should not be updated
+ d.RemoveObserver (o1);
+ d.PostNotification ("hello", target, null);
+ Assert.AreEqual (2, count);
+ Assert.AreEqual (2, count2);
+
+ // Remove the last observer, there should be no change in count
+ d.RemoveObserver (o2);
+ d.PostNotification ("hello", target, null);
+ Assert.AreEqual (2, count);
+ Assert.AreEqual (2, count2);
+
+ // Test removing all observers
+ count = 0;
+ o1 = d.AddObserver ("hello", target, (x,dd)=>{
+ count++;
+ Console.WriteLine ("Here");
+ });
+ o2 = d.AddObserver ("hello", target, (y,ee)=> {count++;});
+ d.RemoveEveryObserver ();
+ d.PostNotification ("hello", target, null);
+ Assert.AreEqual (0, count);
+
+ // Test removing from a callback
+ count = 0;
+ o2 = d.AddObserver ("hello", target, (y,ee)=> {count++; d.RemoveObserver (o2); });
+ d.PostNotification ("hello", target, null);
+ Assert.AreEqual (1, count);
+ d.PostNotification ("hello", target, null);
+ Assert.AreEqual (1, count);
+ }
+
+ }
+}
+
diff --git a/tests/api-shared/ObjCRuntime/RegistrarTest.cs b/tests/api-shared/ObjCRuntime/RegistrarTest.cs
new file mode 100644
index 000000000000..596cfbffd3d8
--- /dev/null
+++ b/tests/api-shared/ObjCRuntime/RegistrarTest.cs
@@ -0,0 +1,69 @@
+//
+// Unit tests for the registrars.
+//
+// Authors:
+// Rolf Bjarne Kvinge
+//
+// Copyright 2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif __IOS__
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+namespace XamarinTests.ObjCRuntime {
+ [TestFixture]
+ public class RegistrarSharedTest {
+ public static Registrars CurrentRegistrar {
+ get {
+ return Registrar.CurrentRegistrar;
+ }
+ }
+
+ [Test]
+ public void IntPtrCtor ()
+ {
+ IntPtr ptr = IntPtr.Zero;
+ try {
+ ptr = Messaging.IntPtr_objc_msgSend (Class.GetHandle (typeof (IntPtrCtorTestClass)), Selector.GetHandle ("alloc"));
+ ptr = Messaging.IntPtr_objc_msgSend (ptr, Selector.GetHandle ("init"));
+ var ex = Assert.Throws (() => Messaging.bool_objc_msgSend_IntPtr (ptr, Selector.GetHandle ("conformsToProtocol:"), IntPtr.Zero));
+ var msg = string.Format ("Failed to marshal the Objective-C object 0x{0} (type: IntPtrCtorTestClass). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'XamarinTests.ObjCRuntime.RegistrarSharedTest+IntPtrCtorTestClass' does not have a constructor that takes one IntPtr argument).", ptr.ToString ("x"));
+ if (CurrentRegistrar == Registrars.Static || CurrentRegistrar == Registrars.OldStatic) {
+ msg += "\nAdditional information:\n\tSelector: conformsToProtocol:\n\tMethod: ";
+#if !XAMCORE_2_0
+#if __IOS__
+ msg += "MonoTouch.";
+#else
+ msg += "MonoMac.";
+#endif
+#endif
+ msg += "Foundation.NSObject:InvokeConformsToProtocol (intptr)\n";
+ }
+ Assert.AreEqual (msg, ex.Message, "#message");
+ } finally {
+ Messaging.void_objc_msgSend (ptr, Selector.GetHandle ("release"));
+ }
+ }
+
+ [Register ("IntPtrCtorTestClass")]
+ class IntPtrCtorTestClass : NSObject {
+ [Export ("initWithFoo:")]
+ public IntPtrCtorTestClass (int foo)
+ {
+ Console.WriteLine ("foo1");
+ }
+ }
+ }
+}
diff --git a/tests/apitest/.gitignore b/tests/apitest/.gitignore
new file mode 100644
index 000000000000..0cef782ba01b
--- /dev/null
+++ b/tests/apitest/.gitignore
@@ -0,0 +1,2 @@
+TestResult*
+build/
diff --git a/tests/apitest/Info.plist b/tests/apitest/Info.plist
new file mode 100644
index 000000000000..803c7af5e180
--- /dev/null
+++ b/tests/apitest/Info.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ CFBundleDisplayName
+ apitest
+ CFBundleIdentifier
+ com.xamarin.apitest
+ CFBundleName
+ apitest
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.7
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/tests/apitest/apitest.csproj b/tests/apitest/apitest.csproj
new file mode 100644
index 000000000000..2cbc657ad2ae
--- /dev/null
+++ b/tests/apitest/apitest.csproj
@@ -0,0 +1,155 @@
+
+
+
+ Debug
+ x86
+ {7A0EDA95-30A6-43E1-AD43-368AD95AC48B}
+ {42C0BBD9-55CE-4FC1-8D90-A7348ABAFB23};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ apitest
+ apitest
+ v4.5
+ Resources
+
+
+ true
+ full
+ false
+ bin\x86\Debug
+ DEBUG;MONOMAC
+ prompt
+ 4
+ false
+ false
+ Mac Developer
+ false
+ false
+ false
+ false
+ x86
+
+
+ true
+ bin\x86\Debug
+ MONOMAC
+ prompt
+ 4
+ false
+ true
+ Developer ID Application
+ true
+ false
+ true
+ false
+ SdkOnly
+ x86
+
+
+
+
+
+
+
+
+
+ ..\..\..\xamarin-macios\external\guiunit\bin\net_4_5\GuiUnit.exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ shared\ObjCRuntime\RegistrarTest.cs
+
+
+ shared\ObjCRuntime\Registrar.cs
+
+
+ src\CoreFoundation\CFNotificationCenterTest.cs
+
+
+ shared\PlatformInfo.cs
+
+
+ shared\MacTestMain.cs
+
+
+
+
+
+
+
diff --git a/tests/apitest/src/AVFoundation/AVAudioIONode.cs b/tests/apitest/src/AVFoundation/AVAudioIONode.cs
new file mode 100644
index 000000000000..f31e4fab8e4c
--- /dev/null
+++ b/tests/apitest/src/AVFoundation/AVAudioIONode.cs
@@ -0,0 +1,35 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.AudioUnit;
+using MonoMac.AVFoundation;
+using AUUnit = MonoMac.AudioUnit.AudioUnit;
+#else
+using AppKit;
+using Foundation;
+using AudioUnit;
+using AUUnit = AudioUnit.AudioUnit;
+using AVFoundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class AVAudioIONodeTests
+ {
+ [Test]
+ public void AVAudioIONodeTests_AudioUnitTest ()
+ {
+ Asserts.EnsureYosemite ();
+
+ AVAudioEngine eng = new AVAudioEngine();
+ AVAudioIONode node = eng.OutputNode;
+ AUUnit unit = node.AudioUnit;
+ unit.GetElementCount (AudioUnitScopeType.Global);
+ // Make sure this doens't crash.
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AVFoundation/AVPlayerLayerTest.cs b/tests/apitest/src/AVFoundation/AVPlayerLayerTest.cs
new file mode 100644
index 000000000000..4525a5227470
--- /dev/null
+++ b/tests/apitest/src/AVFoundation/AVPlayerLayerTest.cs
@@ -0,0 +1,33 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.AudioUnit;
+using MonoMac.AVFoundation;
+#else
+using AppKit;
+using Foundation;
+using AudioUnit;
+using AVFoundation;
+using AUUnit = AudioUnit.AudioUnit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class AVPlayerLayerTests
+ {
+ [Test]
+ public void AVPlayerLayer_VideoGravity ()
+ {
+ AVPlayerLayer layer = new AVPlayerLayer ();
+#if XAMCORE_2_0
+ Assert.IsNotNull (layer.VideoGravity);
+#else
+ Assert.IsNotNull (layer.LayerVideoGravity);
+#endif
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSAppearance.cs b/tests/apitest/src/AppKit/NSAppearance.cs
new file mode 100644
index 000000000000..1218984110fb
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSAppearance.cs
@@ -0,0 +1,58 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+using nfloat = System.Single;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSAppearanceTests
+ {
+ [Test]
+ public void NSAppearanceShouldLoadAppearanceNamed ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var appearance = NSAppearance.GetAppearance (NSAppearance.NameVibrantDark);
+ Assert.IsNotNull (appearance, "NSAppearanceShouldLoadAppearanceNamed - Failed to initialize appearance VibrantDark");
+ Assert.AreEqual (appearance.Name, NSAppearance.NameVibrantDark.ToString (), "NSAppearanceShouldLoadAppearanceNamed - Appearance initialized with incorrect name.");
+ }
+
+#if FALSE // Test failing, exception doesn't appear to be thrown during test, throw correctly running in an app.
+ [Test]
+ public void NSAppearanceConstructorShouldFailWithInvalidName ()
+ {
+ bool exceptionHit = false;
+
+ try {
+ var appearance = new NSAppearance ("InvalidNameTest", null);
+ } catch (ArgumentException e) {
+ exceptionHit = true;
+ }
+
+ Assert.IsTrue (exceptionHit, "NSAppearanceConstructorShouldFailWithInvalidName - No exception thrown while initializing appearance with invalid name.");
+ }
+#endif
+
+ [Test]
+ public void NSAppearanceShouldChangeCurrentAppearance ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var appearance = NSAppearance.CurrentAppearance;
+
+ NSAppearance.CurrentAppearance = NSAppearance.GetAppearance (NSAppearance.NameVibrantDark);
+
+ Assert.AreNotEqual (appearance, NSAppearance.CurrentAppearance, "NSAppearanceShouldChangeCurrentAppearance - Failed to change appearance.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSApplication.cs b/tests/apitest/src/AppKit/NSApplication.cs
new file mode 100644
index 000000000000..80f661476a4e
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSApplication.cs
@@ -0,0 +1,25 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSApplicationTests
+ {
+ [Test]
+ public void NSApplication_SendActionNullTest ()
+ {
+ NSApplication.SharedApplication.SendAction(new Selector("undo:"), null, new NSObject ());
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSCellTest.cs b/tests/apitest/src/AppKit/NSCellTest.cs
new file mode 100644
index 000000000000..fb8e947132cb
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSCellTest.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if XAMCORE_2_0
+using AppKit;
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+
+using NUnit.Framework;
+
+namespace MonoMacFixtures.AppKit
+{
+ [TestFixture]
+ public class CellTest
+ {
+ [Test]
+ public void CopyTest ()
+ {
+ using (var cell = new CustomCell ())
+ Check (cell.Handle);
+ }
+
+ [Test]
+ public void CopyDerivedTest ()
+ {
+ using (var cell = new DerivedCell ())
+ Check (cell.Handle);
+ }
+
+ void Check (IntPtr cell_handle)
+ {
+ var clone_ptr = IntPtr_objc_msgSend (cell_handle, Selector.GetHandle ("copyWithZone:"), IntPtr.Zero);
+// Console.WriteLine ("Created cell 0x{0} (GCHandle: 0x{2}) with clone 0x{1} (GCHandle: 0x{3})", cell_handle.ToString ("x"), clone_ptr.ToString ("x"), GetGCHandle (cell_handle).ToString ("x"), GetGCHandle (clone_ptr).ToString ("x"));
+
+ Assert.AreNotEqual (GetGCHandle (cell_handle), GetGCHandle (clone_ptr), "gchandle #1");
+ CustomCell.expectedHandle = cell_handle;
+ objc_msgSend (Class.GetHandle (typeof (CustomCell)), Selector.GetHandle ("foo:"), cell_handle);
+
+ Assert.AreNotEqual (GetGCHandle (cell_handle), GetGCHandle (clone_ptr), "gchandle #2");
+ CustomCell.expectedHandle = clone_ptr;
+ objc_msgSend (Class.GetHandle (typeof (CustomCell)), Selector.GetHandle ("foo:"), clone_ptr);
+
+ Assert.AreNotEqual (GetGCHandle (cell_handle), GetGCHandle (clone_ptr), "gchandle #3");
+
+ objc_msgSend (clone_ptr, Selector.GetHandle ("release"));
+ }
+
+ [DllImport ("__Internal", EntryPoint = "xamarin_get_gchandle")]
+ extern static int GetGCHandle (IntPtr ptr);
+
+ const string LIBOBJC_DYLIB = "/usr/lib/libobjc.dylib";
+
+ [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
+ public extern static IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector, IntPtr p1);
+
+ [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
+ public extern static void objc_msgSend (IntPtr receiver, IntPtr selector, IntPtr p1);
+
+ [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
+ public extern static void objc_msgSend (IntPtr receiver, IntPtr selector);
+
+ [DllImport (LIBOBJC_DYLIB)]
+ internal extern static IntPtr object_getInstanceVariable (IntPtr cls, string name, out IntPtr value);
+ }
+
+ class CustomCell : NSCell {
+ public static IntPtr expectedHandle;
+
+ public CustomCell (IntPtr ptr) : base (ptr) { }
+ public CustomCell () { }
+
+ [Export ("foo:")]
+ public static void Foo (CustomCell mySelf)
+ {
+ Assert.AreEqual (expectedHandle, mySelf.Handle, "Handle");
+ }
+ }
+
+ class DerivedCell : CustomCell
+ {
+ public DerivedCell (IntPtr ptr) : base (ptr) { }
+ public DerivedCell () { }
+
+ public override NSObject Copy (NSZone zone)
+ {
+ return base.Copy (zone);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSClipView.cs b/tests/apitest/src/AppKit/NSClipView.cs
new file mode 100644
index 000000000000..ee77bdd975ef
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSClipView.cs
@@ -0,0 +1,33 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using CoreGraphics;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSClipViewTests
+ {
+ [Test]
+ public void NSClipViewConstrainBoundsRect ()
+ {
+ Asserts.EnsureMavericks ();
+
+ var clipView = new NSClipView (new CGRect (0, 0, 50, 50));
+ var rect = clipView.ConstrainBoundsRect (new CGRect (10, 10, 30, 30));
+
+ Assert.IsTrue (rect.X == 0, "NSClipViewConstrainBoundsRect - X value was not 0");
+ Assert.IsTrue (rect.Y == 0, "NSClipViewConstrainBoundsRect - Y value was not 0");
+ Assert.IsTrue (rect.Width == 30, "NSClipViewConstrainBoundsRect - Width value was not 30");
+ Assert.IsTrue (rect.Height == 30, "NSClipViewConstrainBoundsRect - Height value was not 30");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSColor.cs b/tests/apitest/src/AppKit/NSColor.cs
new file mode 100644
index 000000000000..95b8a4603e1e
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSColor.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using nfloat = System.Single;
+#else
+using AppKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSColorTests
+ {
+ [Test]
+ public void NSColor_ComponentTests ()
+ {
+ NSColor c = NSColor.Blue;
+ nfloat [] components;
+ c.GetComponents (out components);
+ Assert.IsTrue (0f == components[0], "Red");
+ Assert.IsTrue (0f == components[1], "Green");
+ Assert.IsTrue (1f == components[2], "Blue");
+ }
+
+ [Test]
+ public void SingleComponents ()
+ {
+ var c = NSColor.Red;
+ nfloat[] components;
+ c.GetComponents (out components);
+ Assert.AreEqual (c.RedComponent, components [0], "Red");
+ Assert.AreEqual (c.GreenComponent, components [1], "Green");
+ Assert.AreEqual (c.BlueComponent, components [2], "Blue");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSControl.cs b/tests/apitest/src/AppKit/NSControl.cs
new file mode 100644
index 000000000000..46b8063cb576
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSControl.cs
@@ -0,0 +1,91 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+#else
+using AppKit;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSControlTests
+ {
+ [Test]
+ public void NSControlShouldChangeControlSize ()
+ {
+ Asserts.EnsureYosemite ();
+ var control = new NSButton ();
+ var size = control.ControlSize;
+ control.ControlSize = NSControlSize.Mini;
+
+ Assert.IsFalse (size == control.ControlSize);
+ Assert.IsTrue (control.ControlSize == NSControlSize.Mini);
+ }
+
+ [Test]
+ public void NSControlShouldChangeHighlighted ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSButton ();
+ var highlighted = control.Highlighted;
+ control.Highlighted = !highlighted;
+
+ Assert.IsFalse (highlighted == control.Highlighted);
+ }
+
+ [Test]
+ public void NSControlShouldChangeLineBreakMode ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSButton ();
+ var lineBreak = control.LineBreakMode;
+ control.LineBreakMode = NSLineBreakMode.Clipping;
+
+ Assert.IsTrue (control.LineBreakMode == NSLineBreakMode.Clipping);
+ Assert.IsFalse (lineBreak == control.LineBreakMode);
+ }
+
+ [Test]
+ public void NSControlShouldAddMultipleActivatedEventHandlers ()
+ {
+ var control = new NSButton ();
+
+ int firstHitCount = 0;
+ int secondHitCount = 0;
+
+ control.Activated += (sender, e) => firstHitCount++;
+ control.Activated += (sender, e) => secondHitCount++;
+
+ control.PerformClick (control);
+
+ Assert.IsTrue (firstHitCount == 1, "NSControlShouldAddMultipleActivatedEventHandlers - Did not call first EventHandler");
+ Assert.IsTrue (secondHitCount == 1, "NSControlShouldAddMultipleActivatedEventHandlers - Did not call second EventHandler");
+ }
+
+ [Test]
+ public void NSControlShouldRemoveAndAddActivatedEventHandlers ()
+ {
+ var control = new NSButton ();
+
+ int firstHitCount = 0;
+ int secondHitCount = 0;
+
+ EventHandler firstDelegate = (object sender, EventArgs e) => firstHitCount++;
+
+ control.Activated += firstDelegate;
+ control.Activated -= firstDelegate;
+ control.Activated += (sender, e) => secondHitCount++;
+
+ control.PerformClick (control);
+
+ Assert.IsTrue (firstHitCount == 0, "NSControlShouldRemoveAndAddActivatedEventHandlers - Called first EventHandler after it was removed");
+ Assert.IsTrue (secondHitCount == 1, "NSControlShouldRemoveAndAddActivatedEventHandlers - Did not call second EventHandler");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSDraggingItem.cs b/tests/apitest/src/AppKit/NSDraggingItem.cs
new file mode 100644
index 000000000000..c5f962a474b3
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSDraggingItem.cs
@@ -0,0 +1,46 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSDraggingItemTests
+ {
+ [Test]
+ public void NSDraggingItemConstructorTests ()
+ {
+#pragma warning disable 0219
+ NSDraggingItem item = new NSDraggingItem ((NSString)"Testing");
+ item = new NSDraggingItem (new MyPasteboard ());
+#pragma warning restore 0219
+ }
+
+ class MyPasteboard : NSPasteboardWriting
+ {
+ public override NSObject GetPasteboardPropertyListForType (string type)
+ {
+ return new NSObject ();
+ }
+
+ public override string[] GetWritableTypesForPasteboard (NSPasteboard pasteboard)
+ {
+ return new string [] {};
+ }
+
+ public override NSPasteboardWritingOptions GetWritingOptionsForType (string type, NSPasteboard pasteboard)
+ {
+ return NSPasteboardWritingOptions.WritingPromised;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSGradient.cs b/tests/apitest/src/AppKit/NSGradient.cs
new file mode 100644
index 000000000000..f6377670d64a
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSGradient.cs
@@ -0,0 +1,58 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using nfloat = System.Single;
+#else
+using AppKit;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSGradientTests
+ {
+ [Test]
+ public void NSGradientConstructorTests ()
+ {
+ NSColorSpace colorSpace = NSColorSpace.GenericRGBColorSpace;
+ NSGradient g = new NSGradient (new[] { NSColor.Black, NSColor.White, NSColor.Black }, new[] { 0f, .5f, 1.0f }, colorSpace);
+ Assert.IsNotNull (g);
+ Assert.AreEqual (colorSpace, g.ColorSpace);
+ Assert.AreEqual (3, g.ColorStopsCount);
+
+ // Since we are asking for colors on a gradient, there will be some color blending, even with just black and white.
+ const float closeEnough = .05f;
+ NSColor black = NSColor.Black.UsingColorSpace (NSColorSpace.CalibratedRGB);
+ NSColor white = NSColor.White.UsingColorSpace (NSColorSpace.CalibratedRGB);
+
+ NSColor color;
+ nfloat location;
+
+ g.GetColor (out color, out location, 0);
+ color = color.UsingColorSpace (NSColorSpace.CalibratedRGB);
+ Assert.IsTrue (black.RedComponent - color.RedComponent < closeEnough);
+ Assert.IsTrue (black.BlueComponent - color.BlueComponent < closeEnough);
+ Assert.IsTrue (black.GreenComponent - color.GreenComponent < closeEnough);
+ Assert.AreEqual (0.0f, (float)location);
+
+ g.GetColor (out color, out location, 1);
+ color = color.UsingColorSpace (NSColorSpace.CalibratedRGB);
+ Assert.IsTrue (white.RedComponent - color.RedComponent < closeEnough);
+ Assert.IsTrue (white.BlueComponent - color.BlueComponent < closeEnough);
+ Assert.IsTrue (white.GreenComponent - color.GreenComponent < closeEnough);
+ Assert.AreEqual (0.5f, (float)location);
+
+ g.GetColor (out color, out location, 2);
+ color = color.UsingColorSpace (NSColorSpace.CalibratedRGB);
+ Assert.IsTrue (black.RedComponent - color.RedComponent < closeEnough);
+ Assert.IsTrue (black.BlueComponent - color.BlueComponent < closeEnough);
+ Assert.IsTrue (black.GreenComponent - color.GreenComponent < closeEnough);
+ Assert.AreEqual (1.0f, (float)location);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSImage.cs b/tests/apitest/src/AppKit/NSImage.cs
new file mode 100644
index 000000000000..0116836a27b6
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSImage.cs
@@ -0,0 +1,55 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using CGSize = System.Drawing.SizeF;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+#else
+using AppKit;
+using CoreGraphics;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSImageTests
+ {
+ [Test]
+ public void ImageWithSize ()
+ {
+ Asserts.EnsureMountainLion ();
+ var image = NSImage.ImageWithSize (new CGSize (50, 50), false, rect => {
+ return true;
+ });
+ Assert.IsNotNull (image);
+ }
+
+ [Test]
+ public void NSImageCapInsets ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var image = new NSImage ();
+ image.CapInsets = new NSEdgeInsets (5f, 6f, 7f, 8f);
+
+ Assert.IsNotNull (image.CapInsets);
+ Assert.IsTrue (image.CapInsets.Top == 5f, "NSImageCapInsets - Top value was not 5");
+ Assert.IsTrue (image.CapInsets.Left == 6f, "NSImageCapInsets - Left value was not 6");
+ Assert.IsTrue (image.CapInsets.Bottom == 7f, "NSImageCapInsets - Bottom value was not 7");
+ Assert.IsTrue (image.CapInsets.Right == 8f, "NSImageCapInsets - Right value was not 8");
+ }
+
+ [Test]
+ public void NSImageResizingModeShouldChange ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var image = new NSImage ();
+ image.ResizingMode = NSImageResizingMode.Stretch;
+ Assert.AreEqual (image.ResizingMode, NSImageResizingMode.Stretch, "NSImageResizingMode - Was not equal to Stretch");
+ Assert.AreNotEqual (image.ResizingMode, NSImageResizingMode.Tile, "NSImageResizingMode - Was incorrectly equal to Tile");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSLayoutManagerTests.cs b/tests/apitest/src/AppKit/NSLayoutManagerTests.cs
new file mode 100644
index 000000000000..20b03d9c9361
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSLayoutManagerTests.cs
@@ -0,0 +1,67 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+using CGPoint = System.Drawing.PointF;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+using CoreGraphics;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSLayoutManagerTests
+ {
+ NSLayoutManager manager;
+
+ [SetUp]
+ public void CreateManager ()
+ {
+ // This sets up the global context so our drawing doesn't produce error messages
+ NSBitmapImageRep bitmap = new NSBitmapImageRep (IntPtr.Zero, 1000, 1000, 16, 4, true, false, NSColorSpace.DeviceRGB, 0, 0);
+ NSGraphicsContext.CurrentContext = NSGraphicsContext.FromBitmap (bitmap);
+
+ NSTextStorage storage = new NSTextStorage ("Hello World");
+ NSTextContainer container = new NSTextContainer ();
+ manager = new NSLayoutManager ();
+
+ manager.AddTextContainer (container);
+ storage.AddLayoutManager (manager);
+ }
+
+ [Test]
+ public void NSLayoutManager_DrawBackgroundForGlyphRange ()
+ {
+ manager.DrawBackgroundForGlyphRange (new NSRange (0, 4), new CGPoint (10, 10));
+ }
+
+ [Test]
+ public void NSLayoutManager_DrawGlyphsForGlyphRange ()
+ {
+ manager.DrawGlyphsForGlyphRange (new NSRange (0, 4), new CGPoint (10, 10));
+ }
+
+ [Test]
+ public void NSLayoutManager_CharacterRangeForGlyphRange ()
+ {
+ NSRange pnt;
+ NSRange range = manager.CharacterRangeForGlyphRange (new NSRange (0, 4), out pnt);
+ Assert.IsNotNull (range);
+ }
+
+ [Test]
+ public void NSLayoutManager_GlyphRangeForCharacterRange ()
+ {
+ NSRange pnt;
+ NSRange range = manager.GlyphRangeForCharacterRange (new NSRange (0, 4), out pnt);
+ Assert.IsNotNull (range);
+ }
+ }
+}
diff --git a/tests/apitest/src/AppKit/NSOutlineView.cs b/tests/apitest/src/AppKit/NSOutlineView.cs
new file mode 100644
index 000000000000..f8ae10450931
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSOutlineView.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSOutlineViewTests
+ {
+ [Test]
+ public void NSOutlineView_InsertNull ()
+ {
+ NSOutlineView v = new NSOutlineView ();
+ v.BeginUpdates (); // We do this to prevent a crash: Insert/remove/move only works within a -beginUpdates/-endUpdates block or a View Based TableView
+#if !XAMCORE_2_0
+ v.InsertItems (new NSIndexSet (0), null, NSTableViewAnimationOptions.EffectFade);
+#else
+ v.InsertItems (new NSIndexSet (0), null, NSTableViewAnimation.None);
+#endif
+ v.EndUpdates ();
+ }
+
+ [Test]
+ public void NSOutlineView_DelegateDataSourceNull ()
+ {
+ NSOutlineView v = new NSOutlineView ();
+ v.WeakDelegate = null;
+ v.Delegate = null;
+ v.WeakDataSource = null;
+ v.DataSource = null;
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSPasteboard.cs b/tests/apitest/src/AppKit/NSPasteboard.cs
new file mode 100644
index 000000000000..e88c664d113f
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSPasteboard.cs
@@ -0,0 +1,57 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSPasteboardTests
+ {
+ [Test]
+ public void NSPasteboardTests_WriteObjectTests ()
+ {
+ NSPasteboard b = NSPasteboard.CreateWithUniqueName();
+ b.WriteObjects (new INSPasteboardWriting [] { (NSString)"asfd" });
+ b.WriteObjects (new NSPasteboardWriting [] { new MyPasteboard () });
+#if !XAMCORE_2_0
+ // Awesome backwards compat API
+ b.WriteObjects (new NSPasteboardReading [] { new MyPasteboard2 () });
+#endif
+ }
+
+ class MyPasteboard2 : NSPasteboardReading
+ {
+ public override NSObject InitWithPasteboardPropertyList (NSObject propertyList, string type)
+ {
+ return new NSObject ();
+ }
+ }
+
+ class MyPasteboard : NSPasteboardWriting
+ {
+ public override NSObject GetPasteboardPropertyListForType (string type)
+ {
+ return new NSObject ();
+ }
+
+ public override string[] GetWritableTypesForPasteboard (NSPasteboard pasteboard)
+ {
+ return new string [] {};
+ }
+
+ public override NSPasteboardWritingOptions GetWritingOptionsForType (string type, NSPasteboard pasteboard)
+ {
+ return NSPasteboardWritingOptions.WritingPromised;
+ }
+ }
+ }
+}
diff --git a/tests/apitest/src/AppKit/NSPathControl.cs b/tests/apitest/src/AppKit/NSPathControl.cs
new file mode 100644
index 000000000000..f1e18b30828c
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSPathControl.cs
@@ -0,0 +1,79 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSPathControlTests
+ {
+ [Test]
+ public void NSPathControlShouldSetEditable ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSPathControl ();
+ var editable = control.Editable;
+ control.Editable = !editable;
+
+ Assert.IsTrue (control.Editable != editable, "NSPathControlShouldSetEditable - Failed to change the Editable property");
+ }
+
+ [Test]
+ public void NSPathControlShouldSetAllowedTypes ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSPathControl ();
+ var allowedTypes = control.AllowedTypes;
+ control.AllowedTypes = new [] { (NSString)"exe", (NSString)"jpg" };
+
+ Assert.IsTrue (control.AllowedTypes != allowedTypes, "NSPathControlShouldSetAllowedTypes - Failed to change AllowedTypes property");
+ }
+
+ [Test]
+ public void NSPathControlShouldSetPlaceholderString ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSPathControl ();
+ var placeholderString = control.PlaceholderString;
+ control.PlaceholderString = "Test Placeholder";
+
+ Assert.IsTrue (control.PlaceholderString != placeholderString, "NSPathControlShouldSetPlaceholderString - Failed to change PlaceholderString property");
+ }
+
+ [Test]
+ public void NSPathControlShouldSetPlaceholderAttributedString ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSPathControl ();
+ var placeholderAttributedString = control.PlaceholderAttributedString;
+ control.PlaceholderAttributedString = new NSAttributedString ("Test Placeholder");
+
+ Assert.IsTrue (control.PlaceholderAttributedString != placeholderAttributedString, "NSPathControlShouldSetPlaceholderAttributedString - Failed to change PlaceholderAttributedString property");
+ }
+
+ [Test]
+ public void NSPathControlShouldSetPathItems ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var control = new NSPathControl ();
+ var pathItems = control.PathItems;
+ control.PathItems = new [] { new NSPathControlItem () };
+
+ Assert.IsTrue (control.PathItems != pathItems, "NSPathControlShouldSetPathItems - Failed to set PathItems property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSPathControlItem.cs b/tests/apitest/src/AppKit/NSPathControlItem.cs
new file mode 100644
index 000000000000..bd459ad5431a
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSPathControlItem.cs
@@ -0,0 +1,56 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSPathControlItemTests
+ {
+ [SetUp]
+ public void Setup ()
+ {
+ Asserts.EnsureYosemite ();
+ }
+
+ [Test]
+ public void NSPathControlItemShouldSetTitle ()
+ {
+ var item = new NSPathControlItem ();
+ var title = item.Title;
+ item.Title = "Test";
+
+ Assert.IsTrue (item.Title != title, "NSPathControlShouldSetTitle - Title value did not change.");
+ }
+
+ [Test]
+ public void NSPathControlItemShouldSetAttributedTitle ()
+ {
+ var item = new NSPathControlItem ();
+ var attributedTitle = item.AttributedTitle;
+ item.AttributedTitle = new NSAttributedString ("Test");
+
+ Assert.IsTrue (item.AttributedTitle != attributedTitle, "NSPathControlShouldSetAttributedTitle - AttributedTitle value did not change.");
+
+ }
+
+ [Test]
+ public void NSPathControlItemShouldSetImage ()
+ {
+ var item = new NSPathControlItem ();
+ Assert.IsTrue (item.Image == null, "NSPathControlItemShouldSetImage - Image did not start as null");
+
+ item.Image = new NSImage ();
+ Assert.IsTrue (item.Image != null, "NSPathControlItemShouldSetImage - Failed to set Image property");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSSearchField.cs b/tests/apitest/src/AppKit/NSSearchField.cs
new file mode 100644
index 000000000000..9d16c3da3c9b
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSSearchField.cs
@@ -0,0 +1,71 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSSearchFieldTests
+ {
+ [Test]
+ public void NSSearchFieldShouldSetSearchMenuTemplate ()
+ {
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) < Platform.Mac_10_10)
+ return;
+
+ var searchField = new NSSearchField ();
+ var searchMenuTemplate = searchField.SearchMenuTemplate;
+ searchField.SearchMenuTemplate = new NSMenu ("Test");
+
+ Assert.IsTrue (searchField.SearchMenuTemplate != searchMenuTemplate, "NSSearchFieldShouldSetSearchMenuTemplate - Failed to set the SearchMenuTemplate property.");
+ }
+
+ [Test]
+ public void NSSearchFieldShouldSetSendsWholeSearchString ()
+ {
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) < Platform.Mac_10_10)
+ return;
+
+ var searchField = new NSSearchField ();
+ var sendsWholeSearchString = searchField.SendsWholeSearchString;
+ searchField.SendsWholeSearchString = !sendsWholeSearchString;
+
+ Assert.IsTrue (searchField.SendsWholeSearchString != sendsWholeSearchString, "NSSearchFieldShouldSetSendsWholeSearchString - Failed to set the SendsWholeSearchString property.");
+ }
+
+ [Test]
+ public void NSSearchFieldShouldSetMaximumRecents ()
+ {
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) < Platform.Mac_10_10)
+ return;
+
+ var searchField = new NSSearchField ();
+ var maximumRecents = searchField.MaximumRecents;
+ searchField.MaximumRecents = maximumRecents + 3;
+
+ Assert.IsTrue (searchField.MaximumRecents != maximumRecents, "NSSearchFieldShouldSetMaximumRecents - Failed to set the MaximumRecents property.");
+ }
+
+ [Test]
+ public void NSSearchFieldShouldSetSendsSearchStringImmediately ()
+ {
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) < Platform.Mac_10_10)
+ return;
+
+ var searchField = new NSSearchField ();
+ var sendsSearchStringImmediately = searchField.SendsSearchStringImmediately;
+ searchField.SendsSearchStringImmediately = !sendsSearchStringImmediately;
+
+ Assert.IsTrue (searchField.SendsSearchStringImmediately != sendsSearchStringImmediately, "NSSearchFieldShouldSetSendsSearchStringImmediately - Failed to set the SendsSearchStringImmediately property.");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSSplitViewController.cs b/tests/apitest/src/AppKit/NSSplitViewController.cs
new file mode 100644
index 000000000000..458349a88c27
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSSplitViewController.cs
@@ -0,0 +1,99 @@
+using System;
+using NUnit.Framework;
+using System.Linq;
+
+#if !XAMCORE_2_0
+using System.Drawing;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSSplitViewControllerTests
+ {
+ NSSplitViewController controller;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+
+ controller = new NSSplitViewController ();
+ }
+
+ [Test]
+ public void NSSplitViewControllerShouldChangeSplitView ()
+ {
+ var splitView = controller.SplitView;
+ controller.SplitView = new NSSplitView ();
+
+ Assert.IsFalse (controller.SplitView == splitView, "NSSplitViewControllerShouldChangeSplitView - Failed to set the SplitView property");
+ }
+
+ [Test]
+ public void NSSplitViewControllerShouldChangeSplitViewItems ()
+ {
+ var items = controller.SplitViewItems;
+ controller.SplitViewItems = new NSSplitViewItem [] { new NSSplitViewItem { ViewController = new NSViewController () } };
+
+ Assert.IsFalse (controller.SplitViewItems == items, "NSSplitViewControllerShouldChangeSplitViewItems - Failed to set the SplitViewItems property");
+ }
+
+ [Test]
+ public void NSSplitViewControllerShouldAddSplitViewItem ()
+ {
+ var item = new NSSplitViewItem { ViewController = new NSViewController () };
+ controller.AddSplitViewItem (item);
+
+ Assert.IsTrue (controller.SplitViewItems.Contains (item), "NSSplitViewControllerShouldAddSplitViewItem - Failed to add item");
+ }
+
+ [Test]
+ public void NSSplitViewControllerShouldRemoveSplitViewItem ()
+ {
+ var item = new NSSplitViewItem { ViewController = new NSViewController () };
+ controller.AddSplitViewItem (item);
+
+ Assert.IsTrue (controller.SplitViewItems.Contains (item), "NSSplitViewControllerShouldRemoveSplitViewItem - Failed to add item");
+
+ controller.RemoveSplitViewItem (item);
+
+ Assert.IsFalse (controller.SplitViewItems.Contains (item), "NSSplitViewControllerShouldRemoveSplitViewItem - Failed to remove item");
+ }
+
+ [Test]
+ public void NSSplitViewControllerShouldInsertSplitViewItem ()
+ {
+ controller.AddSplitViewItem (new NSSplitViewItem { ViewController = new NSViewController () });
+ controller.AddSplitViewItem (new NSSplitViewItem { ViewController = new NSViewController () });
+ controller.AddSplitViewItem (new NSSplitViewItem { ViewController = new NSViewController () });
+ var item = new NSSplitViewItem { ViewController = new NSViewController () };
+ controller.InsertSplitViewItem (item, 1);
+
+ Assert.IsTrue (controller.SplitViewItems [1] == item, "NSSplitViewControllerShouldInsertSplitViewItem - Failed to insert the item at the given position.");
+ Assert.IsFalse (controller.SplitViewItems [0] == item, "NSSplitViewControllerShouldInsertSplitViewItem - Inserted the item in the wrong position.");
+ }
+
+ [Test]
+ public void NSSplitViewControllerShouldGetSplitViewItem ()
+ {
+ controller.AddSplitViewItem (new NSSplitViewItem { ViewController = new NSViewController () });
+ controller.AddSplitViewItem (new NSSplitViewItem { ViewController = new NSViewController () });
+ controller.AddSplitViewItem (new NSSplitViewItem { ViewController = new NSViewController () });
+ var viewController = new NSViewController ();
+ var item = new NSSplitViewItem { ViewController = viewController };
+ controller.InsertSplitViewItem (item, 1);
+
+ var retrievedItem = controller.GetSplitViewItem (viewController);
+
+ Assert.IsTrue (retrievedItem == item, "NSSplitViewControllerShouldGetSplitViewItem - Failed to get SplitViewItem from ViewController");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSSplitViewItem.cs b/tests/apitest/src/AppKit/NSSplitViewItem.cs
new file mode 100644
index 000000000000..b58497a00061
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSSplitViewItem.cs
@@ -0,0 +1,77 @@
+using System;
+using NUnit.Framework;
+using System.Linq;
+
+#if !XAMCORE_2_0
+using System.Drawing;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSSplitViewItemTests
+ {
+ NSSplitViewItem item;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+
+ item = new NSSplitViewItem ();
+ }
+
+ [Test]
+ public void NSSplitViewItemShouldCreateFromViewController ()
+ {
+ var viewController = new NSViewController ();
+ var splitViewItem = NSSplitViewItem.FromViewController (viewController);
+
+ Assert.IsFalse (splitViewItem == null, "NSSplitViewItemShouldCreateFromViewController - Returned null");
+ Assert.IsTrue (splitViewItem.ViewController == viewController, "NSSplitViewItemShouldCreateFromViewController - ViewController property not set correctly");
+ }
+
+ [Test]
+ public void NSSplitViewItemShouldChangeViewController ()
+ {
+ var viewController = item.ViewController;
+ item.ViewController = new NSViewController ();
+
+ Assert.IsFalse (item.ViewController == viewController, "NSSplitViewItemShouldChangeViewController - Failed to set the ViewController property");
+ }
+
+ [Test]
+ public void NSSplitViewItemShouldChangeCollapsed ()
+ {
+ var collapsed = item.Collapsed;
+ item.Collapsed = !collapsed;
+
+ Assert.IsFalse (item.Collapsed == collapsed, "NSSplitViewItemShouldChangeCollapsed - Failed to set the Collapsed property");
+ }
+
+ [Test]
+ public void NSSplitViewItemShouldChangeCanCollapse ()
+ {
+ var canCollapse = item.CanCollapse;
+ item.CanCollapse = !canCollapse;
+
+ Assert.IsFalse (item.CanCollapse == canCollapse, "NSSplitViewItemShouldChangeCanCollapse - Failed to set the CanCollapse property");
+ }
+
+ [Test]
+ public void NSSplitViewItemShouldChangeHoldingPriority ()
+ {
+ var holdingPriority = item.HoldingPriority;
+ item.HoldingPriority = 0.35f;
+
+ Assert.IsFalse (item.HoldingPriority == holdingPriority, "NSSplitViewItemShouldChangeHoldingPriority - Failed to set the HoldingPriority property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSStackView.cs b/tests/apitest/src/AppKit/NSStackView.cs
new file mode 100644
index 000000000000..85f29b5d68e4
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSStackView.cs
@@ -0,0 +1,193 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSStackViewTests
+ {
+ NSStackView view;
+ NSView first;
+ NSView second;
+ NSView third;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureMavericks ();
+
+ view = new NSStackView ();
+
+ first = new NSView ();
+ second = new NSView ();
+ third = new NSView ();
+ }
+
+ [Test]
+ public void NSStackViewShouldCreateWithEmptyConstructor ()
+ {
+ Assert.IsNotNull (view, "NSStackViewCreateWithEmptyConstructor - Failed to create view");
+ }
+
+ [Test]
+ public void NSStackViewShouldCreateWithViews ()
+ {
+ view = NSStackView.FromViews (new [] { first, second });
+
+ Assert.IsNotNull (view, "NSStackViewCreateWithViews - Failed to create view");
+ Assert.IsTrue (view.Views.Length == 2, "NSStackViewShouldCreateWithViews - StackView does not have 2 views");
+ }
+
+ [Test]
+ public void NSStackViewShouldAddView ()
+ {view.AddView (new NSView (), NSStackViewGravity.Bottom);
+
+ Assert.IsTrue (view.Views.Length == 1, "NSStackViewShouldAddView - Failed to add view - length was 0");
+ }
+
+ [Test]
+ public void NSStackViewShouldInsertView ()
+ {
+ view.AddView (first, NSStackViewGravity.Trailing);
+ view.AddView (second, NSStackViewGravity.Trailing);
+
+ view.InsertView (third, 1, NSStackViewGravity.Trailing);
+
+ Assert.IsTrue (view.Views.Length == 3, "NSStackViewShouldInsertView - Wrong number of views");
+ Assert.IsTrue (view.Views [1] == third, "NSStackViewShouldInsertView - New view not inserted at the correct location");
+ }
+
+ [Test]
+ public void NSStackViewShouldRemoveView ()
+ {
+ view = NSStackView.FromViews (new [] { first, second });
+
+ view.RemoveView (second);
+
+ Assert.IsTrue (view.Views.Length == 1, "NSStackViewShouldRemoveView - Failed to remove view");
+ }
+
+ [Test]
+ public void NSStackViewShouldSetViews ()
+ {
+ view.SetViews (new [] { first, second }, NSStackViewGravity.Leading);
+
+ Assert.IsTrue (view.Views.Length == 2, "NSStackViewShouldSetViews - Views length was not 0");
+ Assert.IsTrue (view.ViewsInGravity (NSStackViewGravity.Leading).Length == 2, "NSStackViewShouldSetViews - ViewsInGravity Leading was not 2");
+ Assert.IsTrue (view.ViewsInGravity (NSStackViewGravity.Trailing).Length == 0, "NSStackViewShouldSetViews - ViewsInGravity Trailing was not 0");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeAlignment ()
+ {
+ var alignment = view.Alignment;
+ view.Alignment = NSLayoutAttribute.Right;
+
+ Assert.IsFalse (view.Alignment == alignment, "NSStackViewShouldChangeAlignment - Failed to change Alignment property");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeOrientation ()
+ {
+ var orientation = view.Orientation;
+ view.Orientation = NSUserInterfaceLayoutOrientation.Vertical;
+
+ Assert.IsFalse (view.Orientation == orientation, "NSStackViewShouldChangeOrientation - Failed to change Orientation property");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeSpacing ()
+ {
+ var spacing = view.Spacing;
+ view.Spacing = spacing + 3;
+
+ Assert.IsFalse (view.Spacing == spacing, "NSStackViewShouldChangeSpacing - Failed to change Spacing property");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeEdgeInsets ()
+ {
+ var edgeInsets = view.EdgeInsets;
+ view.EdgeInsets = new NSEdgeInsets (20, 20, 20, 20);
+
+ Assert.IsFalse (view.EdgeInsets.Left == edgeInsets.Left, "NSStackViewShouldChangeEdgeInsets - Failed to change EdgeInsets property");
+ Assert.IsFalse (view.EdgeInsets.Right == edgeInsets.Right, "NSStackViewShouldChangeEdgeInsets - Failed to change EdgeInsets property");
+ Assert.IsFalse (view.EdgeInsets.Top == edgeInsets.Top, "NSStackViewShouldChangeEdgeInsets - Failed to change EdgeInsets property");
+ Assert.IsFalse (view.EdgeInsets.Bottom == edgeInsets.Bottom, "NSStackViewShouldChangeEdgeInsets - Failed to change EdgeInsets property");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeHasEqualSpacing ()
+ {
+ var hasEqualSpacing = view.HasEqualSpacing;
+ view.HasEqualSpacing = !hasEqualSpacing;
+
+ Assert.IsFalse (view.HasEqualSpacing == hasEqualSpacing, "NSStackViewShouldChangeHasEqualSpacing - Failed to change HasEqualSpacing property");
+ }
+
+// [Test]
+// public void NSStackViewShouldSetDelegate ()
+// {
+// var view = new NSStackView ();
+// view.Delegate = new NSStackViewDelegate ();
+//
+// Assert.IsNotNull (view.Delegate, "NSStackViewShouldSetDelegate - Delegate property returned null");
+// }
+
+ [Test]
+ public void NSStackViewShouldChangeClippingResistance ()
+ {
+ var clippingResistance = view.ClippingResistancePriorityForOrientation (NSLayoutConstraintOrientation.Vertical);
+ view.SetClippingResistancePriority (clippingResistance + 3, NSLayoutConstraintOrientation.Vertical);
+
+ Assert.IsFalse (view.ClippingResistancePriorityForOrientation (NSLayoutConstraintOrientation.Vertical) == clippingResistance,
+ "NSStackViewShouldChangeClippingResistance - Failed to set ClippingResistance");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeHuggingPriority ()
+ {
+ var huggingPriority = view.HuggingPriority (NSLayoutConstraintOrientation.Horizontal);
+ view.SetHuggingPriority (huggingPriority + 10, NSLayoutConstraintOrientation.Horizontal);
+
+ Assert.IsFalse (view.HuggingPriority (NSLayoutConstraintOrientation.Horizontal) == huggingPriority,
+ "NSStackViewShouldChangeHuggingPriority - Failed to set HuggingPriority");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeCustomSpacing ()
+ {
+ view.AddView (first, NSStackViewGravity.Trailing);
+ view.AddView (second, NSStackViewGravity.Trailing);
+
+ var customSpacing = view.CustomSpacingAfterView (first);
+ view.SetCustomSpacing (10, first);
+
+ Assert.IsFalse (view.CustomSpacingAfterView (first) == customSpacing,
+ "NSStackViewShouldChangeCustomSpacing - Failed to set CustomSpacing");
+ }
+
+ [Test]
+ public void NSStackViewShouldChangeVisibilityPriority ()
+ {
+ view.AddView (first, NSStackViewGravity.Trailing);
+ view.AddView (second, NSStackViewGravity.Trailing);
+
+ var visibilityPriority = view.VisibilityPriority (first);
+ view.SetVisibilityPriority (10, first);
+
+ Assert.IsFalse (view.VisibilityPriority (first) == visibilityPriority,
+ "NSStackViewShouldChangeVisibilityPriority - Failed to set VisibilityPriority");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSStepperCell.cs b/tests/apitest/src/AppKit/NSStepperCell.cs
new file mode 100644
index 000000000000..54d9a059c0a5
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSStepperCell.cs
@@ -0,0 +1,66 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+#else
+using AppKit;
+#endif
+
+namespace apitest
+{
+ [TestFixture]
+ public class NSStepperCellTests
+ {
+ NSStepperCell cell;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ cell = new NSStepperCell ();
+ }
+
+ [Test]
+ public void NSStepperCell_ShouldSetMinValue ()
+ {
+ var minValue = cell.MinValue;
+ cell.MinValue = 3.14159;
+
+ Assert.IsTrue (cell.MinValue != minValue, "NSStepperCell_ShouldSetMinValue - Failed to set the MinValue property");
+ }
+
+ [Test]
+ public void NSStepperCell_ShouldSetMaxValue ()
+ {
+ var maxValue = cell.MaxValue;
+ cell.MaxValue = 3.14159;
+
+ Assert.IsTrue (cell.MinValue != maxValue, "NSStepperCell_ShouldSetMaxValue - Failed to set the MaxValue property");
+ }
+ [Test]
+ public void NSStepperCell_ShouldSetIncrement ()
+ {
+ var increment = cell.Increment;
+ cell.Increment = 3.14159;
+
+ Assert.IsTrue (cell.Increment != increment, "NSStepperCell_ShouldSetIncrement - Failed to set the Increment property");
+ }
+ [Test]
+ public void NSStepperCell_ShouldSetValueWraps ()
+ {
+ var valueWraps = cell.ValueWraps;
+ cell.ValueWraps = !valueWraps;
+
+ Assert.IsTrue (cell.ValueWraps != valueWraps, "NSStepperCell_ShouldSetValueWraps - Failed to set the ValueWraps property");
+ }
+ [Test]
+ public void NSStepperCell_ShouldSetAutoRepeat ()
+ {
+ var autoRepeat = cell.Autorepeat;
+ cell.Autorepeat = !autoRepeat;
+
+ Assert.IsTrue (cell.Autorepeat != autoRepeat, "NSStepperCell_ShouldSetAutoRepeat - Failed to set the Autorepeat property");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSStoryboardSegue.cs b/tests/apitest/src/AppKit/NSStoryboardSegue.cs
new file mode 100644
index 000000000000..a547f598e279
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSStoryboardSegue.cs
@@ -0,0 +1,69 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSStoryboardSegueTests
+ {
+ NSStoryboardSegue segue;
+ NSViewController source;
+ NSViewController destination;
+
+ [SetUp]
+ public void Setup ()
+ {
+ Asserts.EnsureYosemite ();
+
+ source = new NSViewController ();
+ destination = new NSViewController ();
+ segue = new NSStoryboardSegue ("Test", source, destination);
+ }
+
+ [Test]
+ public void NSStoryboardSegueShouldCreateSegueWithConstructor ()
+ {
+ Assert.IsNotNull (segue, "NSStoryboardSegueShouldCreateSegueWithConstructor - Failed to create segue, value is null");
+ }
+
+ [Test]
+ public void NSStoryboardSegueShouldGetIdentifier ()
+ {
+ Assert.IsFalse (string.IsNullOrEmpty (segue.Identifier), "NSStoryboardSegueShouldGetIdentifier - Identifier property was empty or null");
+ }
+
+ [Test]
+ public void NSStoryboardSegueShouldGetSourceController ()
+ {
+ Assert.IsNotNull (segue.SourceController, "NSStoryboardSegueShouldGetSourceController - Source controller was null");
+ Assert.IsTrue (segue.SourceController == source, "NSStoryboardSegueShouldGetSourceController - Source controller did not match the source controller passed into the segue.");
+ }
+
+ [Test]
+ public void NSStoryboardSegueShouldGetDestinationController ()
+ {
+ Assert.IsNotNull (segue.DestinationController, "NSStoryboardSegueShouldGetDestinationController - Destination controller was null");
+ Assert.IsTrue (segue.DestinationController == destination, "NSStoryboardSegueShouldGetDestinationController - Destination controller did not mass the destination controller passed into the segue.");
+ }
+
+#if false // Crashes when run in test from command line, works from an actual app
+ [Test]
+ public void NSStoryboardSegueShouldCreateSegueWithStaticMethod ()
+ {
+ var segue = NSStoryboardSegue.FromIdentifier ("Test", new NSViewController (), new NSViewController (), () => {
+ });
+ Assert.IsNotNull (segue);
+ }
+#endif
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTabViewController.cs b/tests/apitest/src/AppKit/NSTabViewController.cs
new file mode 100644
index 000000000000..4c388d5c416a
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTabViewController.cs
@@ -0,0 +1,154 @@
+using System;
+using NUnit.Framework;
+using System.Linq;
+
+#if !XAMCORE_2_0
+using System.Drawing;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSTabViewControllerTests
+ {
+ NSTabViewController controller;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+
+ controller = new NSTabViewController ();
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldChangeTabStyle ()
+ {
+ var tabStyle = controller.TabStyle;
+ controller.TabStyle = NSTabViewControllerTabStyle.Toolbar;
+
+ Assert.IsFalse (controller.TabStyle == tabStyle, "NSTabViewControllerShouldChangeTabStyle - Failed to set the TabStyle property");
+ }
+
+// [Test]
+// public void NSTabViewControllerShouldChangeTabView ()
+// {
+// var tabView = controller.TabView;
+// controller.TabView = new NSTabView ();
+//
+// Assert.IsFalse (controller.TabView == tabView, "NSTabViewControllerShouldChangeTabView - Failed to set the TabView property");
+// }
+
+ [Test]
+ public void NSTabViewControllerShouldChangeSegmentedControl ()
+ {
+ // This API was removed in 10.11
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) >= Platform.Mac_10_11)
+ return;
+
+ var segmentedControl = controller.SegmentedControl;
+ controller.SegmentedControl = new NSSegmentedControl ();
+
+ Assert.IsFalse (controller.SegmentedControl == segmentedControl, "NSTabViewControllerShouldChangeSegmentedControl - Failed to set the SegmentedControl property");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldChangeTransitionOptions ()
+ {
+ var options = controller.TransitionOptions;
+ controller.TransitionOptions = NSViewControllerTransitionOptions.Crossfade | NSViewControllerTransitionOptions.SlideRight;
+
+ Assert.IsFalse (controller.TransitionOptions == options, "NSTabViewControllerShouldChangeTransitionOptions - Failed to set the TransitionOptions property");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldChangeCanPropagateSelectedChildViewControllerTitle ()
+ {
+ var canPropogate = controller.CanPropagateSelectedChildViewControllerTitle;
+ controller.CanPropagateSelectedChildViewControllerTitle = !canPropogate;
+
+ Assert.IsFalse (controller.CanPropagateSelectedChildViewControllerTitle == canPropogate, "NSTabViewControllerShouldChangeCanPropagateSelectedChildViewControllerTitle - Failed to set the CanPropagateSelectedChildViewControllerTitle property");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldChangeTabViewItems ()
+ {
+ var items = controller.TabViewItems;
+ controller.TabViewItems = new NSTabViewItem [] { new NSTabViewItem { ViewController = new NSViewController () } };
+
+ Assert.IsFalse (controller.TabViewItems == items, "NSTabViewControllerShouldChangeTabViewItems - Failed to set the TabViewItems property");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldChangeSelectedTabViewItemIndex ()
+ {
+ controller.TabViewItems = new NSTabViewItem [] {
+ new NSTabViewItem { ViewController = new NSViewController () },
+ new NSTabViewItem { ViewController = new NSViewController () },
+ new NSTabViewItem { ViewController = new NSViewController () }
+ };
+
+ var index = controller.SelectedTabViewItemIndex;
+ controller.SelectedTabViewItemIndex = (index + 1) % 3;
+
+ Assert.IsFalse (controller.SelectedTabViewItemIndex == index, "NSTabViewControllerShouldChangeSelectedTabViewItemIndex - Failed to set the SelectedTabViewItemIndex property");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldAddTabViewItem ()
+ {
+ var item = new NSTabViewItem { ViewController = new NSViewController () };
+ controller.AddTabViewItem (item);
+
+ Assert.IsTrue (controller.TabViewItems.Contains (item), "NSTabViewControllerShouldAddTabViewItem - Failed to add TabViewItem");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldRemoveTabViewItem ()
+ {
+ var item = new NSTabViewItem { ViewController = new NSViewController () };
+ controller.AddTabViewItem (item);
+
+ Assert.IsTrue (controller.TabViewItems.Contains (item), "NSTabViewControllerShouldRemoveTabViewItem - Failed to add item");
+
+ controller.RemoveTabViewItem (item);
+
+ Assert.IsFalse (controller.TabViewItems.Contains (item), "NSTabViewControllerShouldRemoveTabViewItem - Failed to remove item");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldInsertTabViewItem ()
+ {
+ controller.AddTabViewItem (new NSTabViewItem { ViewController = new NSViewController () });
+ controller.AddTabViewItem (new NSTabViewItem { ViewController = new NSViewController () });
+ controller.AddTabViewItem (new NSTabViewItem { ViewController = new NSViewController () });
+ var item = new NSTabViewItem { ViewController = new NSViewController () };
+ controller.InsertTabViewItem (item, 1);
+
+ Assert.IsTrue (controller.TabViewItems [1] == item, "NSTabViewControllerShouldInsertTabViewItem - Failed to insert the item at the given position.");
+ Assert.IsFalse (controller.TabViewItems [0] == item, "NSTabViewControllerShouldInsertTabViewItem - Inserted the item in the wrong position.");
+ }
+
+ [Test]
+ public void NSTabViewControllerShouldGetTabViewItem ()
+ {
+ controller.AddTabViewItem (new NSTabViewItem { ViewController = new NSViewController () });
+ controller.AddTabViewItem (new NSTabViewItem { ViewController = new NSViewController () });
+ controller.AddTabViewItem (new NSTabViewItem { ViewController = new NSViewController () });
+ var viewController = new NSViewController ();
+ var item = new NSTabViewItem { ViewController = viewController };
+ controller.InsertTabViewItem (item, 1);
+
+ var retrievedItem = controller.GetTabViewItem (viewController);
+
+ Assert.IsTrue (retrievedItem == item, "NSTabViewControllerShouldGetTabViewItem - Failed to get TabViewItem from ViewController");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSTabViewItem.cs b/tests/apitest/src/AppKit/NSTabViewItem.cs
new file mode 100644
index 000000000000..e4ed6bd78571
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTabViewItem.cs
@@ -0,0 +1,49 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSTabViewItemTests
+ {
+ NSTabViewItem item;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ item = new NSTabViewItem ();
+ }
+
+ [Test]
+ public void NSTabViewItemShouldChangeImage ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var image = item.Image;
+ item.Image = new NSImage ();
+
+ Assert.IsFalse (item.Image == image, "NSTabViewItemShouldChangeImage - Failed to set the Image property");
+ }
+
+ [Test]
+ public void NSTabViewItemShouldChangeViewController ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var vc = item.ViewController;
+ item.ViewController = new NSViewController ();
+
+ Assert.IsFalse (item.ViewController == vc, "NSTabViewItemShouldChangeViewController - Failed to set the ViewController property");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTableColumn.cs b/tests/apitest/src/AppKit/NSTableColumn.cs
new file mode 100644
index 000000000000..a13fa483fdac
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTableColumn.cs
@@ -0,0 +1,38 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSTableColumnTests
+ {
+ NSTableColumn column;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ column = new NSTableColumn ();
+ }
+
+ [Test]
+ public void NSTableColumnShouldChangeTitle ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var title = column.Title;
+ column.Title = "Test";
+
+ Assert.IsFalse (column.Title == title, "NSTableColumnShouldChangeTitle - Failed to set the Title property");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTableRowView.cs b/tests/apitest/src/AppKit/NSTableRowView.cs
new file mode 100644
index 000000000000..a03b012ee1c3
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTableRowView.cs
@@ -0,0 +1,49 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSTableRowViewTests
+ {
+ NSTableRowView view;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ view = new NSTableRowView ();
+ }
+
+ [Test]
+ public void NSTableRowViewShouldChangePreviousRowSelected ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var selected = view.PreviousRowSelected;
+ view.PreviousRowSelected = !selected;
+
+ Assert.IsFalse (view.PreviousRowSelected == selected, "NSTableRowViewShouldChangePreviousRowSelected - Failed to set the PreviousRowSelected property");
+ }
+
+ [Test]
+ public void NSTableRowViewShouldChangeNextRowSelected ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var selected = view.NextRowSelected;
+ view.NextRowSelected = !selected;
+
+ Assert.IsFalse (view.NextRowSelected == selected, "NSTableRowViewShouldChangeNextRowSelected - Failed to set the NextRowSelected property");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTableView.cs b/tests/apitest/src/AppKit/NSTableView.cs
new file mode 100644
index 000000000000..db3477ec6a1d
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTableView.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSTableViewTests
+ {
+ [Test]
+ public void NSTableView_DelegateDataSourceNull ()
+ {
+ NSTableView v = new NSTableView ();
+ v.WeakDelegate = null;
+ v.Delegate = null;
+ v.WeakDataSource = null;
+ v.DataSource = null;
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTextField.cs b/tests/apitest/src/AppKit/NSTextField.cs
new file mode 100644
index 000000000000..391f4eb3c127
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTextField.cs
@@ -0,0 +1,48 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSTextFieldTests
+ {
+ NSTextField textField;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ textField = new NSTextField ();
+ }
+
+ [Test]
+ public void NSTextFieldShouldChangePlaceholderString ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var placeholder = textField.PlaceholderString;
+ textField.PlaceholderString = "Test";
+
+ Assert.IsFalse (textField.PlaceholderString == placeholder, "NSTextFieldShouldChangePlaceholderString - Failed to set the PlaceholderString property");
+ }
+
+ [Test]
+ public void NSTextFieldShouldChangePlaceholderAttributedString ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var placeholder = textField.PlaceholderAttributedString;
+ textField.PlaceholderAttributedString = new NSAttributedString ("Test");
+
+ Assert.IsFalse (textField.PlaceholderAttributedString == placeholder, "NSTextFieldShouldChangePlaceholderAttributedString - Failed to set the PlaceholderAttributedString property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSTextFinder.cs b/tests/apitest/src/AppKit/NSTextFinder.cs
new file mode 100644
index 000000000000..4bca3e89f0d9
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTextFinder.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.AudioUnit;
+using MonoMac.AudioToolbox;
+using MonoMac.Foundation;
+using nuint = System.UInt32;
+#else
+using AppKit;
+using AudioUnit;
+using AudioToolbox;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSTextFinderTests
+ {
+ [Test]
+ public void NSTextFinderConstructor ()
+ {
+ NSTextFinder f = new NSTextFinder ();
+ Assert.IsNotNull (f);
+
+ FinderClient client = new FinderClient ();
+ f.Client = client;
+ }
+
+ class FinderClient : NSTextFinderClient
+ {
+ public override bool AllowsMultipleSelection { get { return true; } }
+
+ public override bool Editable { get { return true; } }
+
+ public override string String { get { return "Testing One Two Three"; } }
+
+ public override NSRange FirstSelectedRange { get { return new NSRange(); } }
+
+ public override NSArray SelectedRanges { get; set; }
+
+ public override NSArray VisibleCharacterRanges { get { return new NSArray(); } }
+
+ public override bool Selectable { get { return true; } }
+
+ public override string StringAtIndexeffectiveRangeendsWithSearchBoundary (nuint characterIndex, ref NSRange outRange, bool outFlag)
+ {
+ return String;
+ }
+
+ public override nuint StringLength ()
+ {
+ return (nuint)String.Length;
+ }
+
+ public override void ScrollRangeToVisible (NSRange range)
+ {
+ }
+
+ public override bool ShouldReplaceCharactersInRangeswithStrings (NSArray ranges, NSArray strings)
+ {
+ return false;
+ }
+
+ public override void ReplaceCharactersInRangewithString (NSRange range, string str)
+ {
+ }
+
+ public override void DidReplaceCharacters ()
+ {
+ }
+
+ public override NSView ContentViewAtIndexeffectiveCharacterRange (nuint index, ref NSRange outRange)
+ {
+ return null;
+ }
+
+ public override NSArray RectsForCharacterRange (NSRange range)
+ {
+ return null;
+ }
+
+ public override void DrawCharactersInRangeforContentView (NSRange range, NSView view)
+ {
+ }
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTextInputClient.cs b/tests/apitest/src/AppKit/NSTextInputClient.cs
new file mode 100644
index 000000000000..f07d71bb2d97
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTextInputClient.cs
@@ -0,0 +1,117 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using CGPoint = System.Drawing.PointF;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using CoreGraphics;
+using Foundation;
+#endif
+
+namespace apitest
+{
+ [TestFixture]
+ public class NSTextInputClient
+ {
+ NSTextView textView;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ textView = new NSTextView (new CGRect (0, 0, 37, 120));
+ textView.Value = "This is a new string";
+ Assert.AreEqual (textView.Value, "This is a new string", "NSTextInputClientSetup - Failed to set value");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldInsertText ()
+ {
+ textView.InsertText ((NSString)"Test", new NSRange (5, 4));
+
+ Assert.AreEqual (textView.Value, "This Test new string", "NSTextInputClient_ShouldInsertText - Failed to insert text");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldMarkText ()
+ {
+ textView.SetMarkedText ((NSString)"Testing", new NSRange (0, 10), new NSRange (5, 4));
+
+ Assert.IsTrue (textView.HasMarkedText, "NSTextInputClient_ShouldMarkText - Failed to mark text");
+ Assert.AreEqual (textView.MarkedRange, new NSRange (5, 7));
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetValidAttributesForMarkedText ()
+ {
+ Assert.IsTrue (textView.ValidAttributesForMarkedText.Length > 0, "NSTextInputClient_ShouldGetValidAttributesForMarkedTExt - No valid attributes");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldUnmarkText ()
+ {
+ textView.SetMarkedText ((NSString)"Testing", new NSRange (0, 10), new NSRange (5, 4));
+
+ Assert.IsTrue (textView.HasMarkedText, "NSTextInputClient_ShouldUnMarkText - Failed to mark text");
+
+ textView.UnmarkText ();
+
+ Assert.IsFalse (textView.HasMarkedText, "NSTextInputClient_ShouldUnmarkText - Failed to Unmark text");
+ Assert.IsTrue (textView.MarkedRange.Length == 0, "NSTextInputClient_ShouldUnmarkText - MarkedRange is not 0");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetAttributedSubstring ()
+ {
+ NSRange range;
+ var attributedString = textView.GetAttributedSubstring (new NSRange (10, 15), out range);
+
+ Assert.AreEqual (attributedString.Value, "new string", "NSTextInputClient_ShouldGetAttributedSubstring - Failed to get the correct string");
+ Assert.AreEqual (range, new NSRange (10, 10), "NSTextInputClient_ShouldGetAttributedSubstring - Wrong range value returned");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetFirstRect ()
+ {
+ NSRange range;
+ var rect = textView.GetFirstRect (new NSRange (12, 18), out range);
+
+ Assert.AreEqual (rect, new CGRect (0, 0, 12, 14), "NSTextInputClient_ShouldGetFirstRect - Returned wrong rect");
+ Assert.AreEqual (range, new NSRange (10, 4), "NSTextInputClient_ShouldGetFirstRect - Returned wrong Range");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetAttributedString ()
+ {
+ Assert.AreEqual (textView.AttributedString.Value, "This is a new string", "NSTextInputClient_ShouldGetAttributedString - Returned the wrong attributed string");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetFractionofDistanceThroughGlyph ()
+ {
+ Assert.IsTrue (textView.GetFractionOfDistanceThroughGlyph (new CGPoint (1, 2)) == 0, "NSTextInputClient_ShouldGetFractionofDistanceThroughGlyph - Returned wrong fraaction value");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetBaselineDelta ()
+ {
+ Assert.IsTrue (textView.GetBaselineDelta (4) == 11, "NSTextInputClient_ShouldGetBaselineDelta - Returned wrong baseline delta value");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetDrawsVertically ()
+ {
+ Assert.IsFalse (textView.DrawsVertically (4), "NSTextInputClient_ShouldGetDrawsVertically - Returned wrong value");
+ }
+
+ [Test]
+ public void NSTextInputClient_ShouldGetWindowLevel ()
+ {
+ Assert.AreEqual (textView.WindowLevel, NSWindowLevel.Normal, "NSTextInputClient_ShouldGetWindowLevel - WindowLevel returned the wrong value");
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AppKit/NSTextView.cs b/tests/apitest/src/AppKit/NSTextView.cs
new file mode 100644
index 000000000000..94ea69c06096
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSTextView.cs
@@ -0,0 +1,37 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSTextViewTests
+ {
+ NSTextView view;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ view = new NSTextView ();
+ }
+
+ [Test]
+ public void NSTextViewShouldChangeUsesRolloverButtonForSelection ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var usesRollover = view.UsesRolloverButtonForSelection;
+ view.UsesRolloverButtonForSelection = !usesRollover;
+
+ Assert.IsFalse (view.UsesRolloverButtonForSelection == usesRollover, "NSTextViewShouldChangeUsesRolloverButtonForSelection - Failed to set the UsesRolloverButtonForSelection property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSToolbar.cs b/tests/apitest/src/AppKit/NSToolbar.cs
new file mode 100644
index 000000000000..9b6ecbcaff4c
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSToolbar.cs
@@ -0,0 +1,37 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSToolbarTests
+ {
+ NSToolbar toolbar;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ toolbar = new NSToolbar (NSToolbar.NSToolbarSeparatorItemIdentifier);
+ }
+
+ [Test]
+ public void NSToolbarShouldChangeAllowsExtensionItems ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var allows = toolbar.AllowsExtensionItems;
+ toolbar.AllowsExtensionItems = !allows;
+
+ Assert.IsFalse (toolbar.AllowsExtensionItems == allows, "NSToolbarShouldChangeAllowsExtensionItems - Failed to set the AllowsExtensionItems property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSUserDefaultsController.cs b/tests/apitest/src/AppKit/NSUserDefaultsController.cs
new file mode 100644
index 000000000000..04ca2ae69f84
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSUserDefaultsController.cs
@@ -0,0 +1,77 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSUserDefaultsControllerTests
+ {
+ NSUserDefaultsController controller;
+
+ [Test]
+ public void NSUserDefaultsControllerShouldGetSharedController ()
+ {
+ controller = NSUserDefaultsController.SharedUserDefaultsController;
+
+ Assert.IsNotNull (controller, "NSUserDefaultsControllerShouldGetDefaultController - SharedUserDefaultsController returned null");
+ }
+
+ [Test]
+ public void NSUserDefaultsControllerShouldCreateNewControllerWithDefaultConstructor ()
+ {
+ controller = new NSUserDefaultsController ();
+
+ Assert.IsNotNull (controller, "NSUserDefaultsControllerShouldCreateNewControllerWithDefaultConstructor - Constructor returned null");
+ }
+
+ [Test]
+ public void NSUserDefaultsControllerShouldCreateNewControllerWithNullParameters ()
+ {
+ controller = new NSUserDefaultsController (null, null);
+
+ Assert.IsTrue (controller.Defaults == NSUserDefaults.StandardUserDefaults);
+ Assert.IsTrue (controller.InitialValues == null);
+ Assert.IsNotNull (controller, "NSUserDefaultsControllerShouldCreateNewControllerWithNullParameters - Constructor returned null");
+ }
+
+ [Test]
+ public void NSUserDefaultsControllerShouldCreateNewControllerWithParameters ()
+ {
+ var initialValues = new NSDictionary ();
+ controller = new NSUserDefaultsController (NSUserDefaults.StandardUserDefaults, initialValues);
+
+ Assert.IsTrue (controller.Defaults == NSUserDefaults.StandardUserDefaults);
+ Assert.IsTrue (controller.InitialValues == initialValues);
+ Assert.IsNotNull (controller, "NSUserDefaultsControllerShouldCreateNewControllerWithParameters - Constructor returned null");
+ }
+
+ [Test]
+ public void NSUserDefaultsControllerShouldChangeInitialValues ()
+ {
+ controller = new NSUserDefaultsController (NSUserDefaults.StandardUserDefaults, null);
+ var initialValues = controller.InitialValues;
+ controller.InitialValues = new NSDictionary ();
+
+ Assert.IsFalse (controller.InitialValues == initialValues, "NSUserDefaultsControllerShouldChangeInitialValues - Failed to set the InitialValues property");
+ }
+
+ [Test]
+ public void NSUserDefaultsControllerShouldChangeAppliesImmediately ()
+ {
+ controller = new NSUserDefaultsController (NSUserDefaults.StandardUserDefaults, null);
+ var appliesImmediately = controller.AppliesImmediately;
+ controller.AppliesImmediately = !appliesImmediately;
+
+ Assert.IsFalse (controller.AppliesImmediately == appliesImmediately, "NSUserDefaultsControllerShouldChangeAppliesImmediately - Failed to set the AppliesImmediately property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSView.cs b/tests/apitest/src/AppKit/NSView.cs
new file mode 100644
index 000000000000..595e20ce390a
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSView.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSViewTests
+ {
+ NSView view;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ view = new NSView ();
+ }
+
+ [Test]
+ public void NSViewShouldAddGestureRecognizer ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var length = 0;
+ if (view.GestureRecognizers != null)
+ length = view.GestureRecognizers.Length;
+ view.AddGestureRecognizer (new NSGestureRecognizer ());
+
+ Assert.IsTrue (view.GestureRecognizers.Length == length + 1, "NSViewShouldAddGestureRecognizer - Failed to add recognizer, count didn't change.");
+ }
+
+ [Test]
+ public void NSViewShouldRemoveGestureRecognizer ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var recognizer = new NSClickGestureRecognizer ();
+ view.AddGestureRecognizer (recognizer);
+
+ Assert.IsTrue (view.GestureRecognizers.Length != 0, "NSViewShouldRemoveGestureRecognizer - Failed to add gesture recognizer");
+
+ view.RemoveGestureRecognizer (recognizer);
+
+ Assert.IsTrue (view.GestureRecognizers.Length == 0, "NSViewShouldRemoveGestureRecognizer - Failed to remove gesture recognizer");
+ }
+
+ [Test]
+ public void NSViewShouldChangeGestureRecognizers ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var recognizers = view.GestureRecognizers;
+ view.GestureRecognizers = new NSGestureRecognizer [] { new NSClickGestureRecognizer (), new NSPanGestureRecognizer () };
+
+ Assert.IsFalse (view.GestureRecognizers == recognizers);
+ }
+
+ [Test]
+ public void AllItemsWithNSMenuShouldAllowNull ()
+ {
+ // Can't test typeof (NSResponder) since it is abstract
+ List types = new List { typeof (NSCell), typeof (NSMenuItem), typeof (NSPathControl),
+ typeof (NSPopUpButton), typeof (NSPopUpButtonCell) };
+ if (IntPtr.Size == 4)
+ types.Add (typeof (NSMenuView)); // NSMenuView is 32-bit only
+
+ foreach (Type t in types) {
+ object o = Activator.CreateInstance (t);
+ PropertyInfo prop = t.GetProperty("Menu", BindingFlags.Public | BindingFlags.Instance);
+ prop.SetValue (o, null, null);
+ }
+
+ // NSStateBarItem can't be created via default constructor
+ NSStatusBar.SystemStatusBar.CreateStatusItem (10).Menu = null;
+ }
+ }
+}
diff --git a/tests/apitest/src/AppKit/NSViewController.cs b/tests/apitest/src/AppKit/NSViewController.cs
new file mode 100644
index 000000000000..ef791df70917
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSViewController.cs
@@ -0,0 +1,70 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using System.Drawing;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSViewControllerTests
+ {
+ NSViewController controller;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ controller = new NSViewController ();
+ }
+
+ [Test]
+ public void NSViewControllerShouldAddChildViewController ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var child = new NSViewController ();
+ controller.AddChildViewController (child);
+
+ Assert.IsTrue (controller.ChildViewControllers.Length == 1, "NSViewControllerShouldAddChildViewControllers - Failed to add child view controller");
+ }
+
+ [Test]
+ public void NSViewControllerShouldRemoveChildViewController ()
+ {
+ Asserts.EnsureYosemite ();
+
+ var child = new NSViewController ();
+ controller.AddChildViewController (child);
+
+ Assert.IsTrue (controller.ChildViewControllers.Length == 1, "NSViewControllerShouldRemoveChildViewControllers - Failed to add child view controller");
+
+ controller.RemoveChildViewController (0);
+
+ Assert.IsTrue (controller.ChildViewControllers.Length == 0, "NSViewControllerShouldRemoveChildViewController - Failed to remove child view controller");
+ }
+
+ [Test]
+ public void NSViewControllerShouldInsertChildViewController ()
+ {
+ Asserts.EnsureYosemite ();
+
+ controller.AddChildViewController (new NSViewController ());
+ controller.AddChildViewController (new NSViewController ());
+
+ Assert.IsTrue (controller.ChildViewControllers.Length == 2, "NSViewControllerShouldInsertChildViewController - Failed to add child view controller");
+
+ var child = new NSViewController ();
+ controller.InsertChildViewController (child, 1);
+
+ Assert.IsTrue (controller.ChildViewControllers.Length == 3, "NSViewControllerShouldInsertChildViewController - Failed to insert child view controller");
+ Assert.IsTrue (controller.ChildViewControllers [1] == child, "NSViewControllerShouldInsertChildViewController - Inserted child view controller at the wrong index.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSVisualEffectView.cs b/tests/apitest/src/AppKit/NSVisualEffectView.cs
new file mode 100644
index 000000000000..d3c66251e60a
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSVisualEffectView.cs
@@ -0,0 +1,64 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSVisualEffectViewTests
+ {
+ NSVisualEffectView view;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+
+ view = new NSVisualEffectView ();
+ }
+
+ [Test]
+ public void NSVisualEffectViewShouldChangeMaterial ()
+ {
+ var material = view.Material;
+ view.Material = NSVisualEffectMaterial.Titlebar;
+
+ Assert.IsFalse (view.Material == material, "NSVisualEffectViewShouldChangeMaterial - Failed to set the Material property");
+ }
+
+ [Test]
+ public void NSVisualEffectViewShouldChangeBlendingMode ()
+ {
+ var blendingMode = view.BlendingMode;
+ view.BlendingMode = NSVisualEffectBlendingMode.WithinWindow;
+
+ Assert.IsFalse (view.BlendingMode == blendingMode, "NSVisualEffectViewShouldChangeBlendingMode - Failed to set the BlendingMode property");
+ }
+
+ [Test]
+ public void NSVisualEffectViewShouldChangeState ()
+ {
+ var state = view.State;
+ view.State = NSVisualEffectState.Inactive;
+
+ Assert.IsFalse (view.State == state, "NSVisualEffectViewShouldChangeState - Failed to set the State property");
+ }
+
+ [Test]
+ public void NSVisualEffectViewShouldChangeMaskImage ()
+ {
+ var image = view.MaskImage;
+ view.MaskImage = new NSImage ();
+
+ Assert.IsFalse (view.MaskImage == image, "NSVisualEffectViewShouldChangeMaskImage - Failed to set the MaskImage property");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AppKit/NSWindowController.cs b/tests/apitest/src/AppKit/NSWindowController.cs
new file mode 100644
index 000000000000..91ec5232b772
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSWindowController.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public class NSWindowControllerTests
+ {
+ [Test]
+ public void NSWindowController_ShowWindowTest ()
+ {
+ NSWindowController c = new NSWindowController ();
+ c.ShowWindow (null);
+ }
+ }
+}
diff --git a/tests/apitest/src/AppKit/NSWorkspace.cs b/tests/apitest/src/AppKit/NSWorkspace.cs
new file mode 100644
index 000000000000..a71a56aa6abd
--- /dev/null
+++ b/tests/apitest/src/AppKit/NSWorkspace.cs
@@ -0,0 +1,26 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+#else
+using AppKit;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSWorkspaceTests
+ {
+ [Test]
+ public void NSWorkspaceConstantTests ()
+ {
+ Assert.IsNotNull (NSWorkspace.LaunchConfigurationAppleEvent);
+ Assert.IsNotNull (NSWorkspace.LaunchConfigurationArguments);
+ Assert.IsNotNull (NSWorkspace.LaunchConfigurationEnvironment);
+ Assert.IsNotNull (NSWorkspace.LaunchConfigurationArchitecture);
+ }
+ }
+}
diff --git a/tests/apitest/src/Asserts.cs b/tests/apitest/src/Asserts.cs
new file mode 100644
index 000000000000..40c5f7e3898b
--- /dev/null
+++ b/tests/apitest/src/Asserts.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Reflection;
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+#if !XAMCORE_2_0
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using ObjCRuntime;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ public static class Asserts
+ {
+ public static bool IsAtLeastYosemite {
+ get {
+ return PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) >= Platform.Mac_10_10;
+ }
+ }
+
+ public static bool IsAtLeastElCapitan {
+ get {
+ return PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) >= Platform.Mac_10_11;
+ }
+ }
+
+ public static void EnsureYosemite ()
+ {
+ if (!IsAtLeastYosemite)
+ Assert.Pass ("This test requires Yosemite. Skipping");
+ }
+
+ public static void EnsureMavericks ()
+ {
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) < Platform.Mac_10_9)
+ Assert.Pass ("This test requires Mavericks. Skipping");
+ }
+
+ public static void EnsureMountainLion ()
+ {
+ if (PlatformHelper.ToMacVersion (PlatformHelper.GetHostApiPlatform ()) < Platform.Mac_10_8)
+ Assert.Pass ("This test requires Mountain Lion. Skipping");
+ }
+
+ public static void Ensure64Bit ()
+ {
+ if (IntPtr.Size == 4)
+ Assert.Pass ("This test requires 64-bit. Skipping");
+ }
+
+ public static bool SkipDueToAvailabilityAttribute (ICustomAttributeProvider member)
+ {
+ if (member == null)
+ return false;
+ return !member.IsAvailableOnHostPlatform ();
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/AudioUnit/AUGraphTest.cs b/tests/apitest/src/AudioUnit/AUGraphTest.cs
new file mode 100644
index 000000000000..b0b5fa186274
--- /dev/null
+++ b/tests/apitest/src/AudioUnit/AUGraphTest.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.AudioUnit;
+using MonoMac.AudioToolbox;
+#else
+using AppKit;
+using AudioUnit;
+using AudioToolbox;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class AUGraphTests
+ {
+ int graphRenderCallbackCount = 0;
+ int mixerRenderCallbackCount = 0;
+ AUGraph graph;
+#if XAMCORE_2_0
+ AudioUnit.AudioUnit mMixer;
+#else
+ AudioUnit mMixer;
+#endif
+
+ void SetupAUGraph ()
+ {
+ graph = new AUGraph ();
+
+ AudioComponentDescription mixerDescription = new AudioComponentDescription ();
+ mixerDescription.ComponentType = AudioComponentType.Mixer;
+ mixerDescription.ComponentSubType = (int)AudioTypeMixer.MultiChannel;
+ mixerDescription.ComponentFlags = 0;
+ mixerDescription.ComponentFlagsMask = 0;
+ mixerDescription.ComponentManufacturer = AudioComponentManufacturerType.Apple;
+
+ AudioComponentDescription outputDesciption = new AudioComponentDescription ();
+ outputDesciption.ComponentType = AudioComponentType.Output;
+ outputDesciption.ComponentSubType = (int)AudioTypeOutput.System;
+ outputDesciption.ComponentFlags = 0;
+ outputDesciption.ComponentFlagsMask = 0;
+ outputDesciption.ComponentManufacturer = AudioComponentManufacturerType.Apple;
+
+ int mixerNode = graph.AddNode (mixerDescription);
+ int outputNode = graph.AddNode (outputDesciption);
+
+ AUGraphError error = graph.ConnnectNodeInput (mixerNode, 0, outputNode, 0);
+ Assert.AreEqual (AUGraphError.OK, error);
+
+ graph.Open ();
+
+ mMixer = graph.GetNodeInfo (mixerNode);
+
+ AudioUnitStatus status = mMixer.SetElementCount (AudioUnitScopeType.Input, 0);
+ Assert.AreEqual (AudioUnitStatus.OK, status);
+ }
+
+ [Test]
+ public async Task DoTest ()
+ {
+ SetupAUGraph ();
+
+ // One of these has to be commented out depending on old\new build
+ graph.AddRenderNotify (GraphRenderCallback);
+ //graph.RenderCallback += HandleRenderCallback;
+
+ AudioUnitStatus status = mMixer.SetRenderCallback (MixerRenderCallback);
+ Assert.AreEqual (AudioUnitStatus.OK, status );
+
+ await WaitOnGraphAndMixerCallbacks ();
+ }
+
+#if !XAMCORE_2_0
+#pragma warning disable 0612
+ void HandleRenderCallback (object sender, AudioGraphEventArgs e)
+ {
+ graphRenderCallbackCount++;
+ }
+#pragma warning restore 0612
+#endif
+
+ AudioUnitStatus GraphRenderCallback (AudioUnitRenderActionFlags actionFlags, AudioTimeStamp timeStamp, uint busNumber, uint numberFrames, AudioBuffers data)
+ {
+ graphRenderCallbackCount++;
+ return AudioUnitStatus.NoError;
+ }
+
+ AudioUnitStatus MixerRenderCallback (AudioUnitRenderActionFlags actionFlags, AudioTimeStamp timeStamp, uint busNumber, uint numberFrames, AudioBuffers data)
+ {
+ mixerRenderCallbackCount++;
+ return AudioUnitStatus.NoError;
+ }
+
+ async Task WaitOnGraphAndMixerCallbacks ()
+ {
+ graph.Initialize ();
+ graph.Start ();
+
+ // Wait for 1 second, then give up
+ try {
+ for (int i = 0; i < 100; ++i) {
+ if (graphRenderCallbackCount > 0 && mixerRenderCallbackCount > 0)
+ return;
+ await Task.Delay (10);
+ }
+ Assert.Fail ("Did not see events after 1 second");
+ }
+ finally {
+ graph.Stop ();
+ }
+ }
+ }
+}
+
diff --git a/tests/apitest/src/AudioUnit/AudioUnit.cs b/tests/apitest/src/AudioUnit/AudioUnit.cs
new file mode 100644
index 000000000000..b46f8b43da6a
--- /dev/null
+++ b/tests/apitest/src/AudioUnit/AudioUnit.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.AudioUnit;
+using theUnit = MonoMac.AudioUnit.AudioUnit; // Namespace fun
+#else
+using AppKit;
+using AudioUnit;
+using theUnit = AudioUnit.AudioUnit;
+
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class AudioUnitTests
+ {
+ theUnit GetAudioUnitForTest ()
+ {
+ AudioComponentDescription desc = new AudioComponentDescription ();
+ desc.ComponentType = AudioComponentType.Output;
+ desc.ComponentSubType = 1634230636; // 'ahal'
+ desc.ComponentFlags = 0;
+ desc.ComponentFlagsMask = 0;
+ desc.ComponentManufacturer = AudioComponentManufacturerType.Apple;
+
+ AudioComponent comp = AudioComponent.FindNextComponent (null, ref desc);
+ theUnit unit = new theUnit (comp);
+ return unit;
+ }
+
+ [Test]
+ public void GetCurrentDevice_Test ()
+ {
+ theUnit unit = GetAudioUnitForTest ();
+
+ uint device = unit.GetCurrentDevice (AudioUnitScopeType.Global);
+ Assert.IsTrue (device != 0);
+ }
+
+ [Test]
+ public void AudioObjectPropertySelector4CCTest ()
+ {
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.Devices), Is.EqualTo ("dev#"), "dev#");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.DefaultInputDevice), Is.EqualTo ("dIn "), "dIn ");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.DefaultOutputDevice), Is.EqualTo ("dOut"), "dOut");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.DefaultSystemOutputDevice), Is.EqualTo ("sOut"), "sOut");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.TranslateUIDToDevice), Is.EqualTo ("uidd"), "uidd");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.MixStereoToMono), Is.EqualTo ("stmo"), "stmo");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.PlugInList), Is.EqualTo ("plg#"), "plg#");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.TranslateBundleIDToPlugIn), Is.EqualTo ("bidp"), "bidp");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.TransportManagerList), Is.EqualTo ("tmg#"), "tmg#");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.TranslateBundleIDToTransportManager), Is.EqualTo ("tmbi"), "tmbi");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.BoxList), Is.EqualTo ("box#"), "box#");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.TranslateUIDToBox), Is.EqualTo ("uidb"), "uidb");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.ProcessIsMaster), Is.EqualTo ("mast"), "mast");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.IsInitingOrExiting), Is.EqualTo ("inot"), "inot");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.UserIDChanged), Is.EqualTo ("euid"), "euid");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.ProcessIsAudible), Is.EqualTo ("pmut"), "pmut");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.SleepingIsAllowed), Is.EqualTo ("slep"), "slep");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.UnloadingIsAllowed), Is.EqualTo ("unld"), "unld");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.HogModeIsAllowed), Is.EqualTo ("hogr"), "hogr");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.UserSessionIsActiveOrHeadless), Is.EqualTo ("user"), "user");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.ServiceRestarted), Is.EqualTo ("srst"), "srst");
+ Assert.That (FourCC ((int) AudioObjectPropertySelector.PowerHint), Is.EqualTo ("powh"), "powh");
+ }
+
+ [Test]
+ public void AudioObjectPropertyScope4CCTest ()
+ {
+ Assert.That (FourCC ((int) AudioObjectPropertyScope.Global), Is.EqualTo ("glob"), "glob");
+ Assert.That (FourCC ((int) AudioObjectPropertyScope.Input), Is.EqualTo ("inpt"), "inpt");
+ Assert.That (FourCC ((int) AudioObjectPropertyScope.Output), Is.EqualTo ("outp"), "outp");
+ Assert.That (FourCC ((int) AudioObjectPropertyScope.PlayThrough), Is.EqualTo ("ptru"), "ptru");
+ }
+
+ string FourCC (int value)
+ {
+ return new string (new char [] {
+ (char) (byte) (value >> 24),
+ (char) (byte) (value >> 16),
+ (char) (byte) (value >> 8),
+ (char) (byte) value });
+ }
+ }
+}
+
diff --git a/tests/apitest/src/CoreAnimation/CABasicAnimation.cs b/tests/apitest/src/CoreAnimation/CABasicAnimation.cs
new file mode 100644
index 000000000000..2383b79cb4ac
--- /dev/null
+++ b/tests/apitest/src/CoreAnimation/CABasicAnimation.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.CoreAnimation;
+using MonoMac.CoreGraphics;
+using MonoMac.Foundation;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using CoreAnimation;
+using CoreGraphics;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class CABasicAnimationTests
+ {
+ [Test]
+ public void CABasicAnimation_FromToBy_INativeTests ()
+ {
+ CABasicAnimation test = CABasicAnimation.FromKeyPath ("bounds");
+ NSNumber number = new NSNumber (10);
+ test.From = number;
+ Assert.AreEqual (test.From, number, "NSObject from");
+ test.To = number;
+ Assert.AreEqual (test.To, number, "NSObject to");
+ test.By = number;
+ Assert.AreEqual (test.By, number, "NSObject by");
+
+ CGColor color = new CGColor (.5f, .5f, .5f);
+ test = CABasicAnimation.FromKeyPath ("color");
+ test.SetFrom (color);
+ Assert.AreEqual (test.GetFromAs (), color, "INativeObject from");
+ test.SetTo (color);
+ Assert.AreEqual (test.GetToAs (), color, "INativeObject to");
+ test.SetBy (color);
+ Assert.AreEqual (test.GetByAs (), color, "INativeObject by");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/CoreAnimation/CAKeyFrameAnimation.cs b/tests/apitest/src/CoreAnimation/CAKeyFrameAnimation.cs
new file mode 100644
index 000000000000..1ea8000fa544
--- /dev/null
+++ b/tests/apitest/src/CoreAnimation/CAKeyFrameAnimation.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.CoreAnimation;
+using MonoMac.CoreGraphics;
+using MonoMac.Foundation;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using CoreAnimation;
+using CoreGraphics;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class CAKeyFrameAnimationTests
+ {
+ [Test]
+ public void CAKeyFrameAnimation_ValuesTests ()
+ {
+ CAKeyFrameAnimation keyFrameAni = new CAKeyFrameAnimation();
+ keyFrameAni.Values = new NSObject [] { new NSNumber (5) };
+ Assert.AreEqual (1, keyFrameAni.Values.Length);
+ NSNumber arrayNumber = (NSNumber)keyFrameAni.Values[0];
+ Assert.AreEqual (5, arrayNumber.Int32Value);
+
+ CGRect frame = new CGRect (10, 10, 0, 0);
+ CGImage image = CGImage.ScreenImage (0, frame);
+
+ keyFrameAni.SetValues (new CGImage [] {image, image});
+ Assert.AreEqual (2, keyFrameAni.Values.Length);
+ CGImage arrayImage = (CGImage)keyFrameAni.GetValuesAs ()[1];
+ Assert.AreEqual (image.Handle, arrayImage.Handle);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/CoreAnimation/CALayer.cs b/tests/apitest/src/CoreAnimation/CALayer.cs
new file mode 100644
index 000000000000..4e247cbf08ed
--- /dev/null
+++ b/tests/apitest/src/CoreAnimation/CALayer.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.CoreAnimation;
+using MonoMac.CoreGraphics;
+using MonoMac.Foundation;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using CoreAnimation;
+using CoreGraphics;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class CALayerTests
+ {
+ [Test]
+ public void CALayer_ValuesTests ()
+ {
+ CALayer layer = new CALayer ();
+ CGRect frame = new CGRect (10, 10, 0, 0);
+ CGImage image = CGImage.ScreenImage (0, frame);
+ NSImage NSImage = new NSImage ();
+
+ layer.Contents = image;
+ CGImage arrayImage = layer.Contents;
+ Assert.AreEqual (image.Handle, arrayImage.Handle);
+
+ layer.SetContents (NSImage);
+ NSImage arrayNSImage = layer.GetContentsAs ();
+ Assert.AreEqual (NSImage.Handle, arrayNSImage.Handle);
+
+ layer.SetContents (null); // Should not throw
+ layer.Contents = null; // Should not throw
+ }
+ }
+}
+
diff --git a/tests/apitest/src/CoreAnimation/CAOpenGLLayer.cs b/tests/apitest/src/CoreAnimation/CAOpenGLLayer.cs
new file mode 100644
index 000000000000..083343a2907f
--- /dev/null
+++ b/tests/apitest/src/CoreAnimation/CAOpenGLLayer.cs
@@ -0,0 +1,46 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.CoreAnimation;
+using MonoMac.OpenGL;
+using MonoMac.ObjCRuntime;
+#else
+using AppKit;
+using Foundation;
+using CoreAnimation;
+using OpenGL;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class CAOpenGLLayerTest
+ {
+ [Test]
+ public void SubclassedTest ()
+ {
+ using (var layer = new OpenGLLayer ()) {
+ Messaging.IntPtr_objc_msgSend (layer.Handle, Selector.GetHandle ("copyCGLPixelFormatForDisplayMask:"));
+ }
+ }
+ }
+
+ public partial class OpenGLLayer : CAOpenGLLayer
+ {
+ public override CGLPixelFormat CopyCGLPixelFormatForDisplayMask (uint mask)
+ {
+ var attribs = new object [] {
+ CGLPixelFormatAttribute.Accelerated,
+ CGLPixelFormatAttribute.DoubleBuffer,
+ CGLPixelFormatAttribute.ColorSize, 24,
+ CGLPixelFormatAttribute.DepthSize, 16 };
+
+ CGLPixelFormat pixelFormat = new CGLPixelFormat (attribs);
+ return pixelFormat;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/CoreImage/CIFilter.cs b/tests/apitest/src/CoreImage/CIFilter.cs
new file mode 100644
index 000000000000..caee32142eca
--- /dev/null
+++ b/tests/apitest/src/CoreImage/CIFilter.cs
@@ -0,0 +1,42 @@
+using NUnit.Framework;
+using System;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.CoreImage;
+using MonoMac.CoreGraphics;
+using CGSize = System.Drawing.SizeF;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using ObjCRuntime;
+using CoreImage;
+using CoreGraphics;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class CIFilterTests
+ {
+ [Test]
+ public void CIFilterOutputImageTest ()
+ {
+ NSImage nsImg = new NSImage (new CGSize (400, 400));
+ nsImg.LockFocus ();
+ NSColor.Red.SetFill ();
+ NSBezierPath.FillRect (new CGRect (0, 0, 400, 400));
+ nsImg.UnlockFocus ();
+
+ CIImage img = CIImage.FromCGImage (nsImg.CGImage);
+ var gloom = new CIGloom () {
+ Image = img,
+ Intensity = 5,
+ Radius = 1
+ };
+ var output = gloom.OutputImage;
+ Assert.IsNotNull (output, "CIFilterOutputImageTest - output was null");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/DelegateAndDataSourceTest.cs b/tests/apitest/src/DelegateAndDataSourceTest.cs
new file mode 100644
index 000000000000..c1f6b75479cb
--- /dev/null
+++ b/tests/apitest/src/DelegateAndDataSourceTest.cs
@@ -0,0 +1,257 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using NUnit.Framework;
+using System.Runtime.CompilerServices;
+
+
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+#else
+using Foundation;
+using AppKit;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ static class TypeExtension {
+ public static PropertyInfo GetMostDerivedProperty (this Type t, string name)
+ {
+ while (t != null && t != t.BaseType) {
+ var rv = t.GetProperty (name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
+ if (rv != null)
+ return rv;
+ t = t.BaseType;
+ }
+ return null;
+ }
+ }
+
+ [TestFixture]
+ public class DelegateAndDataSourceTest
+ {
+ [Test]
+ public void DelegateAndDataSourceAllowsNull ()
+ {
+ var failingTypes = new Dictionary ();
+
+ // Get our binding assembly
+ var xamMac = typeof (NSObject).Assembly;
+
+ // Walk all non abstract types, looking for things with zero param constructors
+ foreach (Type t in xamMac.GetTypes ().Where (t => !t.IsAbstract)) {
+ // Check availability attributes.
+ if (Asserts.SkipDueToAvailabilityAttribute (t) || skip (t))
+ continue;
+
+ var ctor = t.GetConstructor (BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null);
+
+ // If they have one of the properites we are testing
+ if (ctor != null) {
+ PropertyInfo weakDelegate = t.GetMostDerivedProperty("WeakDelegate");
+ PropertyInfo del = t.GetMostDerivedProperty("Delegate");
+ PropertyInfo weakDataSource = t.GetMostDerivedProperty("WeakDataSource");
+ PropertyInfo dataSource = t.GetMostDerivedProperty("DataSource");
+ if (isValidToTest (weakDelegate) || isValidToTest (del) ||
+ isValidToTest (weakDataSource) || isValidToTest (dataSource) ) {
+ try {
+ // Create an instance and try to set null
+ using (var instance = (IDisposable) ctor.Invoke (null)) {
+ if (isValidToTest (weakDelegate)) {
+ weakDelegate.SetValue (instance, null, null);
+ }
+ if (isValidToTest (del)) {
+ del.SetValue (instance, null, null);
+ }
+ if (isValidToTest (weakDataSource)) {
+ weakDataSource.SetValue (instance, null, null);
+ }
+ if (isValidToTest (dataSource)) {
+ dataSource.SetValue (instance, null, null);
+ }
+ }
+ }
+ catch (TargetInvocationException e) {
+ failingTypes.Add (t, e.InnerException.Message);
+ }
+ catch (Exception e) {
+ Assert.Fail ("Unexpected exception {0} while testing {1}", e, t);
+ }
+ }
+ }
+ }
+
+ GC.Collect (2); // Flush out random failures. Some classes only act badly when disposed
+ if (failingTypes.Count > 0) {
+ Console.WriteLine ("{0} failing types:", failingTypes.Count);
+ foreach (var kvp in failingTypes)
+ Console.WriteLine ("{0}: {1}", kvp.Key, kvp.Value);
+ Assert.Fail ("{0} failing types", failingTypes.Count);
+ }
+ }
+
+ bool skip (Type t)
+ {
+ switch (t.Name) {
+ case "AVAssetResourceLoader":
+ case "AVAssetResourceLoadingRequest":
+ case "AVAssetResourceLoadingContentInformationRequest":
+ case "SCNRenderer":
+ case "NSStream":
+ case "NSSharingServicePicker":
+ case "NSCache":
+ case "NSToolbar":
+ case "NSComboBox":
+ case "NSComboBoxCell":
+ case "IKScannerDeviceView":
+ case "NSUserActivity":
+ case "NSFontPanel":
+ case "AVAudioRecorder":
+ case "MKMapView":
+ case "SKScene":
+ case "NSSpeechRecognizer":
+ case "NSClickGestureRecognizer":
+ // These classes don't do well when you instance them without support
+ return true;
+ case "SCNLayer":
+ case "SCNProgram":
+ if (Asserts.IsAtLeastElCapitan && IntPtr.Size == 4)
+ return true;
+ break;
+ }
+
+ return false;
+ }
+
+// Based on bug 28505 - NSTabView wasn't holding a reference to the Delegate property under new ref count.
+// An ArgumentSemantic (Strong, Retain, etc) is required to keep the reference around so the app doesn't crash after a GC.
+// This test scans all bindings looking for instances where bindings don't have the correct ArgumentSemantic
+ [Test]
+ public void DelegateAndDataSourceHaveArgumentSemanticAttribute ()
+ {
+ var failingTypes = new Dictionary ();
+
+ // Get our binding assembly
+ var xamMac = typeof (NSObject).Assembly;
+
+ foreach (Type t in xamMac.GetTypes ().Where (t => !t.IsAbstract)) {
+ // Check availability attributes.
+ if (Asserts.SkipDueToAvailabilityAttribute (t))
+ continue;
+
+ PropertyInfo weakDelegate = t.GetMostDerivedProperty ("WeakDelegate");
+ PropertyInfo del = t.GetMostDerivedProperty ("Delegate");
+
+ MethodInfo[] accessors = null;
+
+ if (del != null) {
+ if (weakDelegate != null) {
+ if (!weakDelegate.CanWrite)
+ continue;
+
+ accessors = weakDelegate.GetAccessors ();
+ } else {
+ if (!del.CanWrite)
+ continue;
+
+ accessors = del.GetAccessors ();
+ }
+
+ foreach (var accessor in accessors) {
+ var attr = accessor.GetCustomAttributes ().FirstOrDefault (a => a.Selector == "delegate");
+ if (attr == null)
+ continue;
+
+ if (attr.ArgumentSemantic == ArgumentSemantic.None) {
+ failingTypes.Add (t, "Delegate has no ArgumentSemantic set");
+ break;
+ }
+ }
+ }
+
+ PropertyInfo weakDataSource = t.GetMostDerivedProperty ("WeakDataSource");
+ PropertyInfo dataSource = t.GetMostDerivedProperty ("DataSource");
+
+ if (dataSource != null) {
+ accessors = null;
+ if (weakDataSource != null) {
+ if (!weakDataSource.CanWrite)
+ continue;
+
+ accessors = weakDataSource.GetAccessors ();
+ } else {
+ if (!dataSource.CanWrite)
+ continue;
+
+ accessors = dataSource.GetAccessors ();
+ }
+
+ foreach (var accessor in accessors) {
+ var attr = accessor.GetCustomAttributes ().FirstOrDefault (a => a.Selector == "dataSource");
+ if (attr == null)
+ continue;
+
+ if (attr.ArgumentSemantic == ArgumentSemantic.None) {
+ failingTypes.Add (t, "Data Source has no ArgumentSemantic set");
+ break;
+ }
+ }
+ }
+ }
+
+ if (failingTypes.Count > 0) {
+ Console.WriteLine ("{0} failing types:", failingTypes.Count);
+ foreach (var kvp in failingTypes)
+ Console.WriteLine ("{0}: {1}", kvp.Key, kvp.Value);
+ Assert.Fail ("{0} failing types", failingTypes.Count);
+ }
+ }
+
+ [Test]
+ public void TargetArgumentSemanticAttribute ()
+ {
+ var failingTypes = new Dictionary ();
+
+ // Get our binding assembly
+ var xamMac = typeof (NSObject).Assembly;
+
+ foreach (Type t in xamMac.GetTypes ().Where (t => !t.IsAbstract)) {
+ // Check availability attributes.
+ if (Asserts.SkipDueToAvailabilityAttribute (t))
+ continue;
+
+ PropertyInfo target = t.GetMostDerivedProperty ("Target");
+ if (target != null && target.PropertyType == typeof (NSObject)) {
+ MethodInfo[] accessors = target.GetAccessors ();
+ foreach (var accessor in accessors) {
+ var attr = accessor.GetCustomAttributes ().FirstOrDefault (a => a.Selector == "target");
+ if (attr == null)
+ continue;
+
+ if (attr.ArgumentSemantic == ArgumentSemantic.None) {
+ failingTypes.Add (t, "Target has no ArgumentSemantic set");
+ break;
+ }
+ }
+ }
+ }
+
+ if (failingTypes.Count > 0) {
+ Console.WriteLine ("{0} failing types:", failingTypes.Count);
+ foreach (var kvp in failingTypes)
+ Console.WriteLine ("{0}: {1}", kvp.Key, kvp.Value);
+ Assert.Fail ("{0} failing types", failingTypes.Count);
+ }
+ }
+
+ bool isValidToTest (PropertyInfo p)
+ {
+ return p != null && p.CanWrite && !Asserts.SkipDueToAvailabilityAttribute (p);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/DerivedEventTest.cs b/tests/apitest/src/DerivedEventTest.cs
new file mode 100644
index 000000000000..271c0d441aa7
--- /dev/null
+++ b/tests/apitest/src/DerivedEventTest.cs
@@ -0,0 +1,80 @@
+#if XAMCORE_2_0
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+using Foundation;
+using AppKit;
+using CoreGraphics;
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class DerivedEventTest
+ {
+ [Test]
+ public void DerivedEvents_DontStompEachOther ()
+ {
+ NSComboBox b = new NSComboBox (new CGRect (0, 0, 200, 25));
+
+ b.SelectionChanged += (sender, e) => Console.WriteLine ("Change");
+ TestDelegates (b);
+ b.EditingEnded += (sender, e) => Console.WriteLine ("Edit");
+ TestDelegates (b);
+ b.Delegate = null;
+
+ b.EditingEnded += (sender, e) => Console.WriteLine ("Edit");
+ TestDelegates (b);
+ b.SelectionChanged += (sender, e) => Console.WriteLine ("Change");
+ TestDelegates (b);
+ }
+
+ void TestDelegates (NSComboBox b)
+ {
+ NSTextField f = (NSTextField)b;
+ Assert.IsNotNull (b.Delegate, "NSComboBox delegate null");
+ Assert.IsNotNull (f.Delegate, "NSTextField delegate null");
+ Assert.AreEqual (b.Delegate.GetHashCode (), f.Delegate.GetHashCode (), "Delegates are not equal");
+ }
+
+ [Test]
+ public void DerivedEvents_OverwriteThrows ()
+ {
+ TestOverrideThrow (false, true);
+ TestOverrideThrow (true, true);
+#if MONOMAC
+ NSApplication.CheckForEventAndDelegateMismatches = false;
+#else
+ UIApplication.CheckForEventAndDelegateMismatches = false;
+#endif
+ TestOverrideThrow (false, false);
+ TestOverrideThrow (true, false);
+ }
+
+ void TestOverrideThrow (bool eventFirst, bool shouldThrow)
+ {
+ NSComboBox b = new NSComboBox (new CGRect (0, 0, 200, 25));
+ if (eventFirst)
+ b.SelectionChanged += (sender, e) => Console.WriteLine ("Change");
+ else
+ b.Delegate = new NSComboBoxDelegate ();
+
+ bool didThrow = false;
+ try {
+ if (eventFirst)
+ b.Delegate = new NSComboBoxDelegate ();
+ else
+ b.SelectionChanged += (sender, e) => Console.WriteLine ("Change");
+ }
+ catch (System.InvalidOperationException) {
+ didThrow = true;
+ }
+ if (shouldThrow != didThrow)
+ Assert.Fail ("TestOverrideThrow ({0}, {1}) did not have expected thrown status", eventFirst, shouldThrow);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/tests/apitest/src/EveryFrameworkSmokeTest.cs b/tests/apitest/src/EveryFrameworkSmokeTest.cs
new file mode 100644
index 000000000000..ba16756d060e
--- /dev/null
+++ b/tests/apitest/src/EveryFrameworkSmokeTest.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac;
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using AppKit;
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class EveryFrameworkSmokeTests
+ {
+ enum LoadStatus { FailTest, Acceptable };
+
+ LoadStatus CheckLoadFailure (string libraryName, string path)
+ {
+ // Easy pass if the library doesn't even exist on the system...
+ if (!File.Exists (path))
+ return LoadStatus.Acceptable;
+
+ // No bindings for any of these yet
+ switch (libraryName) {
+ case "CryptoTokenKitLibrary":
+ case "FinderSyncLibrary":
+ case "HypervisorLibrary":
+ return LoadStatus.Acceptable;
+ }
+
+ // These libraries only have 64-bit version
+ bool is64Bit = IntPtr.Size == 8;
+ if (!is64Bit) {
+ switch (libraryName) {
+ case "AVKitLibrary":
+ case "AccountsLibrary":
+ case "CloudKitLibrary":
+ case "ContactsLibrary":
+ case "ContactsUILibrary":
+ case "CryptoTokenKitLibrary":
+ case "EventKitLibrary":
+ case "FinderSyncLibrary":
+ case "GLKitLibrary":
+ case "GameControllerLibrary":
+ case "GameplayKitLibrary":
+ case "HypervisorLibrary":
+ case "LocalAuthenticationLibrary":
+ case "MapKitLibrary":
+ case "MediaLibraryLibrary":
+ case "MetalKitLibrary":
+ case "ModelIOLibrary":
+ case "MultipeerConnectivityLibrary":
+ case "NetworkExtensionLibrary":
+ case "NotificationCenterLibrary":
+ case "SceneKitLibrary":
+ case "SocialLibrary":
+ case "SpriteKitLibrary":
+ return LoadStatus.Acceptable;
+ }
+ }
+
+ return LoadStatus.FailTest;
+ }
+
+ [Test]
+ public void ExpectedLibrariesAreLoaded ()
+ {
+ List failures = new List ();
+
+ // In the past, we've missed frameworks in NSObject.mac.cs and shipped brokeness
+ // This test tries to verify every framework listed in Constants either is loaded or expected to not be
+ foreach (FieldInfo info in typeof(Constants).GetFields ().Where (x => x.Name.EndsWith ("Library")) ) {
+ string path = (string)info.GetRawConstantValue ();
+ // Use RTLD_NOLOAD (0x10) so we don't load, just check to see if it is in memory
+ IntPtr handle = Dlfcn.dlopen (path, 0x10);
+ if (handle == IntPtr.Zero && CheckLoadFailure (info.Name, path) == LoadStatus.FailTest)
+ failures.Add (string.Format ("{0} ({1}) failed to load but this was not expected", info.Name, path));
+ }
+
+ if (failures.Count > 0)
+ Assert.Fail (string.Join ("\n", failures));
+ }
+ }
+}
diff --git a/tests/apitest/src/Foundation/AppleScript.cs b/tests/apitest/src/Foundation/AppleScript.cs
new file mode 100644
index 000000000000..9b15cd13bad7
--- /dev/null
+++ b/tests/apitest/src/Foundation/AppleScript.cs
@@ -0,0 +1,36 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+#else
+using AppKit;
+using Foundation;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class AppleScriptTests
+ {
+ [Test]
+ public void AppleScript_BasicTest ()
+ {
+#pragma warning disable 0219
+ const string script = @"tell application ""Finder""
+end tell";
+ NSAppleScript s = new NSAppleScript (script);
+
+ NSDictionary errorInfo;
+ bool success = s.CompileAndReturnError(out errorInfo);
+ Assert.IsTrue (success);
+ Assert.IsNull (errorInfo);
+ Assert.IsTrue (s.Compiled);
+
+ NSAppleEventDescriptor descriptor = s.ExecuteAndReturnError (out errorInfo);
+ Assert.IsNull (errorInfo);
+#pragma warning restore 0219
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/Foundation/NSFormatter.cs b/tests/apitest/src/Foundation/NSFormatter.cs
new file mode 100644
index 000000000000..c3f7490045e3
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSFormatter.cs
@@ -0,0 +1,63 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+#else
+using Foundation;
+using AppKit;
+#endif
+
+namespace apitest
+{
+ [TestFixture]
+ public class NSFormatterTests
+ {
+ NSNumberFormatter formatter;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ formatter = new NSNumberFormatter ();
+ formatter.NumberStyle = NSNumberFormatterStyle.Currency;
+ formatter.Locale = NSLocale.FromLocaleIdentifier ("en-US");
+ }
+
+ [Test]
+ public void NSFormatter_ShouldGetString ()
+ {
+ var str = formatter.StringFor (NSNumber.FromFloat (0.12f));
+
+ Assert.AreEqual (str, "$0.12");
+ }
+
+ [Test]
+ public void NSFormatter_ShouldGetAttributedString ()
+ {
+ var str = formatter.GetAttributedString (NSNumber.FromFloat (3.21f), new NSStringAttributes () { Font = NSFont.SystemFontOfSize (8) });
+
+ Assert.AreEqual (str.Value, "$3.21");
+ }
+
+ [Test]
+ public void NSFormatter_ShouldGetEditingString ()
+ {
+ var str = formatter.EditingStringFor (NSNumber.FromInt32 (14));
+
+ Assert.AreEqual (str, "$14.00");
+ }
+
+ [Test]
+ public void NSFormatter_IsPartialStringValid ()
+ {
+ string newstr;
+ NSString error;
+ formatter.PartialStringValidationEnabled = true;
+ var valid = formatter.IsPartialStringValid ("valid string", out newstr, out error);
+
+ Assert.IsTrue (valid);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/Foundation/NSIndexSet.cs b/tests/apitest/src/Foundation/NSIndexSet.cs
new file mode 100644
index 000000000000..96ab0e5a40db
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSIndexSet.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+using nint = System.Int32;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+using CoreGraphics;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSIndexSetTests
+ {
+ [Test]
+ public void NSIndexSet_ConstructorTest ()
+ {
+#pragma warning disable 0219
+ NSIndexSet a = new NSIndexSet ((int)5);
+#if XAMCORE_2_0
+ NSIndexSet b = new NSIndexSet ((uint)5);
+ NSIndexSet c = new NSIndexSet ((nint)5);
+#endif
+#pragma warning restore 0219
+ }
+
+ [Test]
+ public void NSIndexSet_EmptyToList ()
+ {
+ NSIndexSet a = new NSIndexSet ();
+#pragma warning disable 0219
+ var b = a.ToList ();
+#pragma warning restore 0219
+ }
+
+ [Test]
+ public void NSIndexSet_EmptyToArray ()
+ {
+ NSIndexSet a = new NSIndexSet ();
+#pragma warning disable 0219
+ var b = a.ToArray ();
+#pragma warning restore 0219
+ }
+ }
+}
diff --git a/tests/apitest/src/Foundation/NSLayoutConstraint.cs b/tests/apitest/src/Foundation/NSLayoutConstraint.cs
new file mode 100644
index 000000000000..8df3b63bee99
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSLayoutConstraint.cs
@@ -0,0 +1,70 @@
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+#else
+using AppKit;
+#endif
+using NUnit.Framework;
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSLayoutConstraintTest
+ {
+ [Test]
+ public void FromVisualFormat ()
+ {
+ using (var testView = new TestView ()) {
+ var constraints = NSLayoutConstraint.FromVisualFormat ("[firstLabel]-[secondLabel]-|",
+ NSLayoutFormatOptions.DirectionLeadingToTrailing,
+ "firstLabel", testView.FirstLabel,
+ "secondLabel", testView.SecondLabel
+ );
+
+ const int expectedNumberOfConstraints = 2;
+
+ Assert.That (constraints != null,
+ "'NSLayoutConstraint.FromVisualFormat' method returned no constraints");
+
+ Assert.That (constraints.Length == expectedNumberOfConstraints,
+ string.Format ("Expected number of constraints is {0}. Actual number is {1}", expectedNumberOfConstraints, constraints.Length));
+
+ Assert.That (constraints [0].FirstItem == testView.SecondLabel,
+ "First item of constraints[0] is not testView.SecondLabel");
+ Assert.That (constraints [0].SecondItem == testView.FirstLabel,
+ "Second item of constraints[0] is not testView.FirstLabel");
+ Assert.That (constraints [0].Relation == NSLayoutRelation.Equal,
+ string.Format ("Relation between views of constraints[0] must be `NSLayoutRelation.Equal`. Actual realtion is {0}", constraints [0].Relation));
+
+ Assert.That (constraints [1].FirstItem == testView,
+ "First item of constraints[1] is not testView");
+ Assert.That (constraints [1].SecondItem == testView.SecondLabel,
+ "Second item of constraints[1] is not testView.SecondLabel");
+ Assert.That (constraints [1].Relation == NSLayoutRelation.Equal,
+ string.Format ("Relation between views of constraints[1] must be `NSLayoutRelation.Equal`. Actual realtion is {0}", constraints [1].Relation));
+ }
+ }
+ }
+
+ public class TestView : NSView
+ {
+ public NSTextView FirstLabel { get; private set; }
+
+ public NSTextView SecondLabel { get; private set; }
+
+ public TestView ()
+ {
+ FirstLabel = new NSTextView {
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+
+ AddSubview (FirstLabel);
+
+ SecondLabel = new NSTextView {
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+
+ AddSubview (SecondLabel);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/Foundation/NSObject.cs b/tests/apitest/src/Foundation/NSObject.cs
new file mode 100644
index 000000000000..764fe7b24397
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSObject.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+using nint = System.Int32;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+using CoreGraphics;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSObjectTests
+ {
+ [Test]
+ async public Task NSObjectTests_InvokeTest ()
+ {
+ bool hit = false;
+ NSApplication.SharedApplication.Invoke (() => hit = true, 1);
+ // Wait for 10 second, then give up
+ for (int i = 0; i < 1000; ++i) {
+ if (hit)
+ return;
+ await Task.Delay (10);
+ }
+ Assert.Fail ("Did not see events after 10 second");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/Foundation/NSScriptCommandArgumentDescriptionTest.cs b/tests/apitest/src/Foundation/NSScriptCommandArgumentDescriptionTest.cs
new file mode 100644
index 000000000000..82895f7a4482
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSScriptCommandArgumentDescriptionTest.cs
@@ -0,0 +1,88 @@
+// Copyright 2015 Xamarin, Inc.
+
+using System;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+namespace MonoTouchFixtures.Foundation {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class NSScriptCommandArgumentDescriptionKeysTest {
+ [Test]
+ public void TestAppleEventCodeKey ()
+ {
+ Assert.IsNotNull (NSScriptCommandArgumentDescriptionKeys.AppleEventCodeKey);
+ Assert.AreEqual ("AppleEventCode", NSScriptCommandArgumentDescriptionKeys.AppleEventCodeKey?.ToString ());
+ }
+
+ [Test]
+ public void TestTypeKey ()
+ {
+ Assert.AreEqual ("Type", NSScriptCommandArgumentDescriptionKeys.TypeKey.ToString ());
+ }
+
+ [Test]
+ public void TestOptionalKey ()
+ {
+ Assert.AreEqual ("Optional", NSScriptCommandArgumentDescriptionKeys.OptionalKey.ToString ());
+ }
+ }
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class NSScriptCommandArgumentDescriptionTest {
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestConstructorNameNullOrEmpty (string name)
+ {
+ new NSScriptCommandArgumentDescription (name, "eeee", "NSString", false);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestConstructorEventCodeNullOrEmpty (string eventCode)
+ {
+ new NSScriptCommandArgumentDescription ("name", eventCode, "NSString", false);
+ }
+
+ [TestCase ("srf")]
+ [TestCase ("TooLong")]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestConstructorEventCodeWrongLength (string eventCode)
+ {
+ new NSScriptCommandArgumentDescription ("name", eventCode, "NSString", false);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestConstructorTypeNullOrEmpty (string type)
+ {
+ new NSScriptCommandArgumentDescription ("name", "****", type, false);
+ }
+
+ [TestCase ("name", "cdfd", "NSString", true)]
+ [TestCase ("name", "cdfd", "NSNumber", false)]
+ [TestCase ("name", "****", "NSNumber", true)]
+ [TestCase ("otherName", "****", "NSNumber", false)]
+ public void TestDescription (string name, string code, string type, bool isOptional)
+ {
+ var arg = new NSScriptCommandArgumentDescription (name, code, type, isOptional);
+ var description = arg.Dictionary;
+
+ Assert.AreEqual (code, description [new NSString ("AppleEventCode")].ToString ());
+ Assert.AreEqual (type, description [new NSString ("Type")].ToString ());
+ Assert.AreEqual (isOptional? "Yes" : "No", description [ new NSString ("Optional")].ToString ());
+ }
+ }
+}
diff --git a/tests/apitest/src/Foundation/NSScriptCommandDescriptionTest.cs b/tests/apitest/src/Foundation/NSScriptCommandDescriptionTest.cs
new file mode 100644
index 000000000000..33692bf1eb56
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSScriptCommandDescriptionTest.cs
@@ -0,0 +1,212 @@
+// Copyright 2015 Xamarin, Inc.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+namespace MonoTouchFixtures.Foundation {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class NSScriptCommandDescriptionTest {
+
+ NSScriptCommandDescription scriptDescription = null;
+ Dictionary args;
+ NSScriptCommandDescriptionDictionary dict = null;
+ string suiteName, commandName, cmdClass, eventCode, eventClass, returnType, resultAppleEvent = null;
+
+ [SetUp]
+ public void Init ()
+ {
+ args = new Dictionary {
+ {"firstArg", new NSScriptCommandArgumentDescription {Name="firstArg", AppleEventCode="fArg", Type="integer", IsOptional=true}},
+ {"secondArg", new NSScriptCommandArgumentDescription {Name="secondArg", AppleEventCode="sArg", Type="NSNumber"}},
+ {"thirdArg", new NSScriptCommandArgumentDescription {Name="thirdArg", AppleEventCode="tArg", Type="integer"}}
+ };
+
+ suiteName = "Chromium Suite";
+ commandName = "Exec Python";
+ cmdClass = "NSScriptCommand";
+ eventCode = "ExPy";
+ eventClass = "CrSu";
+ returnType = "NSString";
+ resultAppleEvent = "text";
+ dict = new NSScriptCommandDescriptionDictionary {
+ CommandClass = cmdClass,
+ AppleEventCode = eventCode,
+ AppleEventClassCode = eventClass,
+ Type = returnType,
+ ResultAppleEventCode = resultAppleEvent
+ };
+
+ foreach(var arg in args.Values) {
+ dict.Add (arg);
+ }
+ scriptDescription = NSScriptCommandDescription.Create (suiteName, commandName, dict);
+ }
+
+ [TearDown]
+ public void Dispose ()
+ {
+ if (scriptDescription != null)
+ scriptDescription.Dispose ();
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateWithDictWrongArgDescription ()
+ {
+ var description = new NSScriptCommandDescriptionDictionary ();
+ NSScriptCommandDescription.Create (suiteName, commandName, description);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateWithDictNullOrEmptySuitName (string code)
+ {
+ var description = new NSScriptCommandDescriptionDictionary ();
+ NSScriptCommandDescription.Create (code, commandName, description);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateWithDictNullOrEmptyCommandName (string code)
+ {
+ var description = new NSScriptCommandDescriptionDictionary ();
+ NSScriptCommandDescription.Create (suiteName, code, description);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentNullException))]
+ public void TestCreateWithDictNullDict ()
+ {
+ NSScriptCommandDescriptionDictionary dict = null;
+ NSScriptCommandDescription.Create (suiteName, commandName, dict);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateSuiteNameNullOrEmpty (string code)
+ {
+ NSScriptCommandDescription.Create (code, commandName, dict);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateCommandNameNullOrEmpty (string code)
+ {
+ NSScriptCommandDescription.Create (suiteName, code, dict);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateCmdClassNullOrEmpty (string code)
+ {
+ dict.CommandClass = code;
+ NSScriptCommandDescription.Create (suiteName, commandName, dict);
+ }
+
+ [TestCase ("")]
+ [TestCase (null)]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateEventCodeNullOrEmpty (string code)
+ {
+ dict.AppleEventCode = code;
+ NSScriptCommandDescription.Create (suiteName, commandName, dict);
+ }
+
+ [TestCase ("TooLong")]
+ [TestCase ("srt")]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateEventCodeWrongLength (string code)
+ {
+ dict.AppleEventCode = code;
+ NSScriptCommandDescription.Create (suiteName, commandName, dict);
+ }
+
+ [TestCase ("TooLong")]
+ [TestCase ("srt")]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestCreateResultAppleEventWrongLength (string code)
+ {
+ dict.ResultAppleEventCode = code;
+ NSScriptCommandDescription.Create (suiteName, commandName, dict);
+ }
+
+ [Test]
+ public void TestClassName ()
+ {
+ Assert.AreEqual (cmdClass, scriptDescription.ClassName);
+ }
+
+ [Test]
+ public void TestName ()
+ {
+ Assert.AreEqual (commandName, scriptDescription.Name);
+ }
+
+ [Test]
+ public void TestSuiteName ()
+ {
+ Assert.AreEqual (suiteName, scriptDescription.SuitName);
+ }
+
+ [Test]
+ public void TestArgumentsNames ()
+ {
+ Assert.AreEqual (args.Keys.Count, scriptDescription.ArgumentNames.Length);
+ foreach (var argName in scriptDescription.ArgumentNames) {
+ Assert.IsTrue (args.Keys.Contains (argName), "Arg {0} is missing", argName);
+ }
+ }
+
+ [Test]
+ public void TestAppleEventClassCode ()
+ {
+ Assert.AreEqual (eventClass, scriptDescription.AppleEventClassCode);
+ }
+
+ [Test]
+ public void TestAppleEventCode ()
+ {
+ Assert.AreEqual (eventCode, scriptDescription.AppleEventCode);
+ }
+
+ [Test]
+ public void TestIsOptionalArgument ()
+ {
+ foreach (KeyValuePair kvp in args) {
+ Assert.AreEqual (kvp.Value.IsOptional, scriptDescription.IsOptionalArgument (kvp.Key),
+ "Wrong apple event code for arg {0}", kvp.Key);
+ }
+ }
+
+ [Test]
+ public void TestGetAppleEventCodeForArgument ()
+ {
+ foreach (KeyValuePair kvp in args) {
+ Assert.AreEqual (kvp.Value.AppleEventCode, scriptDescription.GetAppleEventCodeForArgument (kvp.Key),
+ "Wrong apple event code for arg {0}", kvp.Key);
+ }
+ }
+
+ [Test]
+ public void TestReturnType ()
+ {
+ Assert.AreEqual (returnType, scriptDescription.ReturnType);
+ }
+ }
+}
diff --git a/tests/apitest/src/Foundation/NSString.cs b/tests/apitest/src/Foundation/NSString.cs
new file mode 100644
index 000000000000..d7a6857ad5e1
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSString.cs
@@ -0,0 +1,85 @@
+using System;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+using nuint = System.UInt32;
+using nint = System.Int32;
+using CGRect = System.Drawing.RectangleF;
+using CGSize = System.Drawing.SizeF;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+using CoreGraphics;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSStringTests
+ {
+ [Test]
+ public void NSString_LineRangeForRange ()
+ {
+ // Test from http://stackoverflow.com/questions/1085524/how-to-count-the-number-of-lines-in-an-objective-c-string-nsstring
+ NSString input = new NSString("Hey\nHow\nYou\nDoing");
+ int stringLength = (int)input.Length;
+ int numberOfLines = 0;
+ for (int index = 0 ; index < stringLength ; numberOfLines++) {
+ NSRange range = input.LineRangeForRange (new NSRange(index, 0));
+ index = (int)(range.Location + range.Length);
+ }
+ Assert.AreEqual (4, numberOfLines);
+ }
+
+ [Test]
+ public void NSString_GetLineStart ()
+ {
+ NSString input = new NSString("Hey\nHow\nYou\nDoing");
+ nuint start, lineEnd, contentsEnd;
+ input.GetLineStart (out start, out lineEnd, out contentsEnd, new NSRange (5, 11));
+ Assert.AreEqual (4, start);
+ Assert.AreEqual (17, lineEnd);
+ Assert.AreEqual (17, contentsEnd);
+ }
+
+ [Test]
+ public void NSString_BoundingRectWithSize ()
+ {
+ NSString input = new NSString("Hey\nHow\nYou\nDoing");
+ CGRect rect = input.BoundingRectWithSize (new CGSize (20, 30), NSStringDrawingOptions.UsesLineFragmentOrigin | NSStringDrawingOptions.UsesFontLeading, new NSDictionary ());
+ Assert.IsTrue (rect.Width > 0);
+ Assert.IsTrue (rect.Height > 0);
+ }
+ }
+
+ [TestFixture]
+ public class NSAttributedStringTests
+ {
+ [Test]
+ public void NSAttributedString_BoundingRectWithSize ()
+ {
+ NSFont font = NSFont.FromFontName ("Arial", 40);
+ NSAttributedString str = new NSAttributedString("Hello World", font);
+ CGRect rect = str.BoundingRectWithSize (new CGSize (20, 30), NSStringDrawingOptions.UsesLineFragmentOrigin | NSStringDrawingOptions.UsesFontLeading);
+ Assert.IsTrue (rect.Width > 0);
+ Assert.IsTrue (rect.Height > 0);
+ }
+
+ [Test]
+ public void NSAttributedString_GetUrl ()
+ {
+ NSRange range;
+ var str = new NSAttributedString ("Test string with url: http://www.google.com");
+ var url = str.GetUrl (42, out range);
+
+ Assert.IsNotNull (url);
+ Assert.IsTrue (url.AbsoluteString == "http://www.google.com");
+ Assert.IsTrue (range.Location == 22);
+ Assert.IsTrue (range.Length == 21);
+ }
+ }
+}
diff --git a/tests/apitest/src/Foundation/NSThread.cs b/tests/apitest/src/Foundation/NSThread.cs
new file mode 100644
index 000000000000..0f0d59f9ba31
--- /dev/null
+++ b/tests/apitest/src/Foundation/NSThread.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+using nint = System.Int32;
+#else
+using AppKit;
+using ObjCRuntime;
+using Foundation;
+using CoreGraphics;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class NSThreadTests
+ {
+ [Test]
+ public void NSThread_CallStack_Test()
+ {
+ string [] stack = NSThread.NativeCallStack;
+ Assert.IsNotNull (stack);
+ Assert.IsTrue (stack.Length > 0);
+ }
+ }
+}
diff --git a/tests/apitest/src/MonoMac/AssemblyTest.cs b/tests/apitest/src/MonoMac/AssemblyTest.cs
new file mode 100644
index 000000000000..fe9cf7fcbf95
--- /dev/null
+++ b/tests/apitest/src/MonoMac/AssemblyTest.cs
@@ -0,0 +1,32 @@
+//
+// Unit tests for the assembly itself
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoMac.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ public class AssemblyTest {
+
+ static byte[] pkt = { 0x84, 0xe0, 0x4f, 0xf9, 0xcf, 0xb7, 0x90, 0x65 };
+
+ [Test]
+ public void PublicKeyToken ()
+ {
+ Assert.AreEqual (pkt, typeof (NSObject).Assembly.GetName ().GetPublicKeyToken (), "GetPublicKeyToken");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/MonoMac/CBUUID.cs b/tests/apitest/src/MonoMac/CBUUID.cs
new file mode 100644
index 000000000000..02a690e6f2e7
--- /dev/null
+++ b/tests/apitest/src/MonoMac/CBUUID.cs
@@ -0,0 +1,139 @@
+//
+// Unit tests for CBUUID
+//
+// Authors:
+// Aaron Bockover
+//
+// Copyright 2013 Xamarin, Inc.
+//
+
+using System;
+
+#if XAMCORE_2_0
+using Foundation;
+using CoreBluetooth;
+#else
+using MonoMac.Foundation;
+using MonoMac.CoreBluetooth;
+#endif
+
+using NUnit.Framework;
+
+namespace MonoMacFixtures.CoreBluetooth
+{
+ [TestFixture]
+ public class CBUUIDTest
+ {
+ [Test]
+ public void Roundtrip_16bits ()
+ {
+ using (CBUUID uuid = CBUUID.FromString ("1234")) {
+ Assert.That (uuid.Handle, Is.Not.EqualTo (IntPtr.Zero), "Handle");
+ Assert.IsNotNull (uuid.Data, "Data");
+ Assert.That (uuid.Description, Is.EqualTo ("Unknown (<1234>)"), "Description");
+ Assert.That (uuid.ToString (false), Is.EqualTo ("1234"), "ToString(false)");
+ Assert.That (uuid.ToString (true), Is.EqualTo ("00001234-0000-1000-8000-00805f9b34fb"), "ToString(true)");
+ using (CBUUID u2 = CBUUID.FromString (uuid.ToString ())) {
+ Assert.That (u2.ToString (), Is.EqualTo (uuid.ToString ()), "Roundtrip");
+ }
+ }
+ }
+
+ [Test]
+ public void Roundtrip_128bits ()
+ {
+ using (CBUUID uuid = CBUUID.FromString ("12345678-90AB-CDEF-cafe-c80c20443d0b")) {
+ Assert.That (uuid.Handle, Is.Not.EqualTo (IntPtr.Zero), "Handle");
+ Assert.IsNotNull (uuid.Data, "Data");
+ Assert.That (uuid.Description, Is.EqualTo ("Unknown (<12345678 90abcdef cafec80c 20443d0b>)"), "Description");
+ Assert.That (uuid.ToString (false), Is.EqualTo (uuid.ToString (true)), "ToString");
+ using (CBUUID u2 = CBUUID.FromString (uuid.ToString ())) {
+ Assert.That (u2.ToString (), Is.EqualTo (uuid.ToString ()), "Roundtrip");
+ }
+ }
+ }
+
+ static CBUUID MakeFull (byte a, byte b)
+ {
+ return MakeFull (0, 0, a, b);
+ }
+
+ static CBUUID MakeFull (byte a, byte b, byte c, byte d)
+ {
+ return CBUUID.FromBytes (new byte [] {
+ a, b, c, d, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb
+ });
+ }
+
+ [Test]
+ public void Null ()
+ {
+ Assert.That (null as CBUUID, Is.Null);
+ Assert.That (null as CBUUID, Is.EqualTo (null as CBUUID));
+ }
+
+ [Test]
+ public void FullRandomEquals ()
+ {
+ var guid = Guid.NewGuid ();
+ Assert.That (CBUUID.FromBytes (guid.ToByteArray ()),
+ Is.EqualTo (CBUUID.FromBytes (guid.ToByteArray ())));
+ }
+
+ [Test]
+ public void FullRandomNotEqual ()
+ {
+ Assert.That (CBUUID.FromBytes (Guid.NewGuid ().ToByteArray ()),
+ Is.Not.EqualTo (CBUUID.FromBytes (Guid.NewGuid ().ToByteArray ())));
+ }
+
+ [Test]
+ public void PartialEquals ()
+ {
+ var guid = new byte [] { 0xaa, 0xbb };
+ Assert.That (CBUUID.FromBytes (guid),
+ Is.EqualTo (CBUUID.FromBytes (guid)));
+
+ // ObjC exception: Data does not represent a valid UUID
+// guid = new byte [] { 0xaa, 0xbb, 0xcc, 0xdd };
+// Assert.That (CBUUID.FromBytes (guid),
+// Is.EqualTo (CBUUID.FromBytes (guid)));
+
+ Assert.That (CBUUID.FromPartial (0x1234),
+ Is.EqualTo (CBUUID.FromPartial (0x1234)));
+
+ Assert.That (CBUUID.FromString ("1234"),
+ Is.EqualTo (CBUUID.FromBytes (new byte [] { 0x12, 0x34 })));
+
+ // ObjC exception: Data <12345678> does not represent a valid UUID
+// Assert.That (CBUUID.FromString ("12345678"),
+// Is.EqualTo (CBUUID.FromBytes (new byte [] { 0x12, 0x34, 0x56, 0x78 })));
+ }
+
+ [Test]
+ public void PartialEqualsFull ()
+ {
+ Assert.That (CBUUID.FromPartial (0x0127), Is.EqualTo (MakeFull (0x01, 0x27)));
+
+ // ObjC exception: Data does not represent a valid UUID
+// Assert.That (CBUUID.FromBytes (new byte [] { 0xab, 0xcd, 0xef, 0x12 }),
+// Is.EqualTo (MakeFull (0xab, 0xcd, 0xef, 0x12)));
+
+ Assert.That (CBUUID.FromString ("1234"),
+ Is.EqualTo (CBUUID.FromString ("00001234-0000-1000-8000-00805f9b34fb")));
+
+ // ObjC exception: Data <12345678> does not represent a valid UUID
+// Assert.That (CBUUID.FromString ("12345678"),
+// Is.EqualTo (CBUUID.FromString ("12345678-0000-1000-8000-00805f9b34fb")));
+ }
+
+ [Test]
+ public void PartialsOfDifferentSizeNotEqual ()
+ {
+ // ObjC exception: Data <12345678> does not represent a valid UUID
+ Assert.That (CBUUID.FromPartial (0x1234), Is.Not.EqualTo (
+ CBUUID.FromString ("12345678-0000-1000-8000-00805f9b34fb")));
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/NSScriptCommandDescriptionDictionaryTest.cs b/tests/apitest/src/NSScriptCommandDescriptionDictionaryTest.cs
new file mode 100644
index 000000000000..c1283499f92e
--- /dev/null
+++ b/tests/apitest/src/NSScriptCommandDescriptionDictionaryTest.cs
@@ -0,0 +1,95 @@
+
+// Copyright 2015 Xamarin, Inc.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+namespace MonoTouchFixtures.Foundation {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class NSScriptCommandDescriptionDictionaryTest {
+ [Test]
+ public void TestAddNullArgument ()
+ {
+ var arg = new NSScriptCommandArgumentDescription () { AppleEventCode="frgt", Type="text", Name="Foo"};
+ var desc = new NSScriptCommandDescriptionDictionary ();
+ // no exception should happen
+ desc.Add (arg);
+ using (var argKey = new NSString ("Arguments"))
+ using (var nsName = new NSString (arg.Name)) {
+ Assert.IsTrue (desc.Dictionary.ContainsKey (argKey));
+ var argDict = desc.Dictionary [argKey] as NSDictionary;
+ Assert.IsNotNull (argDict);
+ Assert.IsTrue (argDict.ContainsKey (nsName));
+ }
+ }
+
+ [Test]
+ public void TestAddArgument ()
+ {
+ var arg = new NSScriptCommandArgumentDescription () { AppleEventCode="frgt", Type="text", Name="Foo"};
+ var desc = new NSScriptCommandDescriptionDictionary () {Arguments = new NSMutableDictionary ()};
+ // no exception should happen
+ desc.Add (arg);
+ using (var argKey = new NSString ("Arguments"))
+ using (var nsName = new NSString (arg.Name)) {
+ Assert.IsTrue (desc.Dictionary.ContainsKey (argKey));
+ var argDict = desc.Dictionary [argKey] as NSDictionary;
+ Assert.IsNotNull (argDict);
+ Assert.IsTrue (argDict.ContainsKey (nsName));
+ }
+ }
+
+ [Test]
+ public void TestRemoveNoArguments ()
+ {
+ var arg = new NSScriptCommandArgumentDescription () { AppleEventCode="frgt", Type="text", Name="Foo"};
+ var desc = new NSScriptCommandDescriptionDictionary ();
+ // no exception should happen
+ Assert.IsFalse (desc.Remove (arg));
+ }
+
+ [Test]
+ public void TestRemoveMissingArgument ()
+ {
+ var arg = new NSScriptCommandArgumentDescription () { AppleEventCode="frgt", Type="text", Name="Foo"};
+ var desc = new NSScriptCommandDescriptionDictionary () {Arguments = new NSMutableDictionary ()};
+ // no exception should happen
+ Assert.IsFalse (desc.Remove (arg));
+ }
+
+ [Test]
+ public void RemoveArgument ()
+ {
+ var arg = new NSScriptCommandArgumentDescription () { AppleEventCode="frgt", Type="text", Name="Foo"};
+ var desc = new NSScriptCommandDescriptionDictionary () {Arguments = new NSMutableDictionary ()};
+ // no exception should happen
+ desc.Add (arg);
+ using (var argKey = new NSString ("Arguments"))
+ using (var nsName = new NSString (arg.Name)) {
+ Assert.IsTrue (desc.Dictionary.ContainsKey (argKey));
+ var argDict = desc.Dictionary [argKey] as NSDictionary;
+ Assert.IsNotNull (argDict);
+ Assert.IsTrue (argDict.ContainsKey (nsName));
+ }
+ desc.Remove (arg);
+ using (var argKey = new NSString ("Arguments"))
+ using (var nsName = new NSString (arg.Name)) {
+ Assert.IsTrue (desc.Dictionary.ContainsKey (argKey));
+ var argDict = desc.Dictionary [argKey] as NSDictionary;
+ Assert.IsNotNull (argDict);
+ Assert.IsFalse (argDict.ContainsKey (nsName));
+ }
+ }
+ }
+}
diff --git a/tests/apitest/src/ObjCRuntime/ClassTest.cs b/tests/apitest/src/ObjCRuntime/ClassTest.cs
new file mode 100644
index 000000000000..89a5ea6ccc63
--- /dev/null
+++ b/tests/apitest/src/ObjCRuntime/ClassTest.cs
@@ -0,0 +1,51 @@
+//
+// Unit tests for Class
+//
+// Authors:
+// Rolf Bjarne Kvinge
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+namespace MonoMacFixtures.ObjCRuntime {
+
+ [TestFixture]
+ public class ClassTest {
+ [Test]
+ public void ThrowOnMissingNativeClassTest ()
+ {
+ bool saved = Class.ThrowOnInitFailure;
+
+ Class.ThrowOnInitFailure = true;
+ try {
+ new InexistentClass ();
+ Assert.Fail ("a");
+ } catch {
+ // OK
+ } finally {
+ Class.ThrowOnInitFailure = saved;
+ }
+ }
+
+ [Register ("Inexistent", true)]
+ public class InexistentClass : NSObject {
+ public override IntPtr ClassHandle {
+ get {
+ return Class.GetHandle (GetType ().Name);
+ }
+ }
+ }
+ }
+}
diff --git a/tests/apitest/src/ObjCRuntime/Messaging.cs b/tests/apitest/src/ObjCRuntime/Messaging.cs
new file mode 100644
index 000000000000..b3be5b134461
--- /dev/null
+++ b/tests/apitest/src/ObjCRuntime/Messaging.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Runtime.InteropServices;
+
+public class Messaging
+{
+ const string LIBOBJC_DYLIB = "/usr/lib/libobjc.dylib";
+
+
+ [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
+ public extern static IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector);
+
+ [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
+ public extern static bool bool_objc_msgSend_IntPtr (IntPtr receiver, IntPtr selector, IntPtr p1);
+
+ [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
+ public extern static void void_objc_msgSend (IntPtr receiver, IntPtr selector);
+}
+
diff --git a/tests/apitest/src/SceneKit/SCNGeometrySource.cs b/tests/apitest/src/SceneKit/SCNGeometrySource.cs
new file mode 100644
index 000000000000..8714154970e7
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SCNGeometrySource.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+using MonoMac.SceneKit;
+#else
+using Foundation;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SCNGeometrySourceTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNGeometrySourceSemanticTest ()
+ {
+ Asserts.EnsureMountainLion ();
+ Assert.IsNotNull (SCNGeometrySourceSemantic.Color, "Color");
+ }
+
+ private bool isValidEnumForPlatform (SCNGeometrySourceSemantics value)
+ {
+ if (Asserts.IsAtLeastYosemite)
+ return true;
+
+ switch (value) {
+ case SCNGeometrySourceSemantics.Color:
+ case SCNGeometrySourceSemantics.Normal:
+ case SCNGeometrySourceSemantics.Texcoord:
+ case SCNGeometrySourceSemantics.Vertex:
+ return true;
+
+ case SCNGeometrySourceSemantics.BoneIndices:
+ case SCNGeometrySourceSemantics.BoneWeights:
+ case SCNGeometrySourceSemantics.EdgeCrease:
+ case SCNGeometrySourceSemantics.VertexCrease:
+ default: // this might need updating with 10.11
+ return Asserts.IsAtLeastYosemite;
+ }
+ }
+
+ [Test]
+ public void SCNGeometrySource_FromDataTest ()
+ {
+ Asserts.EnsureMountainLion ();
+#pragma warning disable 0219
+ SCNGeometrySource d = SCNGeometrySource.FromData (new NSData (), SCNGeometrySourceSemantic.Color, 1, false, 1, 1, 1, 1);
+ foreach (SCNGeometrySourceSemantics s in Enum.GetValues (typeof (SCNGeometrySourceSemantics))) {
+ if (!isValidEnumForPlatform (s))
+ continue;
+ d = SCNGeometrySource.FromData (new NSData (), s, 1, false, 1, 1, 1, 1);
+ }
+#pragma warning restore 0219
+ }
+
+ [Test]
+ public void SCNGeometrySource_BoneStringTests () // These were radar://17782603
+ {
+ Asserts.EnsureYosemite ();
+
+#pragma warning disable 0219
+ SCNGeometrySource d = SCNGeometrySource.FromData (new NSData (), SCNGeometrySourceSemantic.BoneWeights, 1, false, 1, 1, 1, 1);
+ d = SCNGeometrySource.FromData (new NSData (), SCNGeometrySourceSemantic.BoneIndices, 1, false, 1, 1, 1, 1);
+#pragma warning restore 0219
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SceneKit/SCNMaterial.cs b/tests/apitest/src/SceneKit/SCNMaterial.cs
new file mode 100644
index 000000000000..9cb425d3a7af
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SCNMaterial.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.SceneKit;
+#else
+using AppKit;
+using Foundation;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SCNMaterialTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureMavericks ();
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNMaterial_ShaderModifierTest_Weak ()
+ {
+ if (IntPtr.Size == 8) // API is 64-bit only
+ {
+ SCNMaterial m = new SCNMaterial ();
+ m.WeakShaderModifiers = new NSDictionary ();
+ }
+ }
+
+ [Test]
+ public void SCNMaterial_ShaderModifierTest ()
+ {
+ if (IntPtr.Size == 8) // API is 64-bit only
+ {
+ SCNMaterial m = new SCNMaterial ();
+ m.ShaderModifiers = new SCNShaderModifiers ();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SceneKit/SCNNode.cs b/tests/apitest/src/SceneKit/SCNNode.cs
new file mode 100644
index 000000000000..56a206a553ba
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SCNNode.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.CoreAnimation;
+using MonoMac.SceneKit;
+#else
+using AppKit;
+using Foundation;
+using CoreAnimation;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SCNNodeTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureMavericks ();
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNNode_AddAnimation ()
+ {
+ SCNNode c = new SCNNode ();
+ CABasicAnimation a = CABasicAnimation.FromKeyPath ("hidden");
+ NSString key = new NSString("MyKey");
+ c.AddAnimation (a, key);
+ CAPropertyAnimation cur = (CAPropertyAnimation)c.GetAnimation (key);
+ Assert.IsNotNull (cur);
+ Assert.AreEqual (cur.KeyPath, "hidden");
+ c.RemoveAnimation (key);
+ cur = (CAPropertyAnimation)c.GetAnimation (key);
+ Assert.IsNull (cur);
+ }
+
+ [Test]
+ public void SCNNode_SetPhysicsBodyTest ()
+ {
+ Asserts.EnsureYosemite ();
+
+ if (IntPtr.Size == 8)
+ {
+ // Create a new empty scene
+ var Scene = new SCNScene ();
+
+ var floorNode = SCNNode.Create ();
+ Scene.RootNode.AddChildNode (floorNode);
+
+ floorNode.PhysicsBody = SCNPhysicsBody.CreateStaticBody ();
+ Scene.PhysicsWorld.Speed = 0;
+ }
+ }
+
+ [Test]
+ public void SCNNode_GeometryNullTest ()
+ {
+ var floorNode = SCNNode.Create ();
+ floorNode.Geometry = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SceneKit/SCNScene.cs b/tests/apitest/src/SceneKit/SCNScene.cs
new file mode 100644
index 000000000000..b1b35ad3461e
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SCNScene.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+using MonoMac.SceneKit;
+
+#else
+using Foundation;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SCNSceneTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNSceneLoadingOptions_AnimationImportPolicyTest ()
+ {
+ SCNSceneLoadingOptions o = new SCNSceneLoadingOptions ();
+ RoundTrip (o, SCNAnimationImportPolicy.Play);
+ RoundTrip (o, SCNAnimationImportPolicy.PlayRepeatedly);
+ RoundTrip (o, SCNAnimationImportPolicy.DoNotPlay);
+ RoundTrip (o, SCNAnimationImportPolicy.PlayUsingSceneTimeBase);
+ }
+
+ [Test]
+ public void SCNSceneLoadingOptions_AnimationImportPolicyTestKeysNonNull ()
+ {
+ Assert.IsNotNull (SCNSceneSourceLoading.AnimationImportPolicyPlay);
+ Assert.IsNotNull (SCNSceneSourceLoading.AnimationImportPolicyPlayRepeatedly);
+ Assert.IsNotNull (SCNSceneSourceLoading.AnimationImportPolicyDoNotPlay);
+ Assert.IsNotNull (SCNSceneSourceLoading.AnimationImportPolicyPlayUsingSceneTimeBase);
+ }
+
+ void RoundTrip (SCNSceneLoadingOptions o, SCNAnimationImportPolicy policy)
+ {
+ o.AnimationImportPolicy = policy;
+ Assert.IsTrue (o.AnimationImportPolicy == policy);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SceneKit/SCNView.cs b/tests/apitest/src/SceneKit/SCNView.cs
new file mode 100644
index 000000000000..9828d574e579
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SCNView.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.CoreAnimation;
+using MonoMac.SceneKit;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using Foundation;
+using CoreAnimation;
+using CoreGraphics;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SCNViewTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNView_TechniqueSetterTest ()
+ {
+ SCNView v = new SCNView (new CGRect (), (NSDictionary) null);
+ SCNTechnique t = SCNTechnique.Create (new NSDictionary ());
+ v.Technique = t;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SceneKit/SCNWorld.cs b/tests/apitest/src/SceneKit/SCNWorld.cs
new file mode 100644
index 000000000000..18af5764e563
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SCNWorld.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.CoreAnimation;
+using MonoMac.SceneKit;
+#else
+using AppKit;
+using Foundation;
+using CoreAnimation;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SCNWorldTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureMavericks ();
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNNode_BackfaceCulling ()
+ {
+ Asserts.EnsureYosemite ();
+
+ if (IntPtr.Size == 8)
+ {
+ Assert.IsNotNull (SCNPhysicsTestKeys.BackfaceCullingKey);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SceneKit/SceneKit.cs b/tests/apitest/src/SceneKit/SceneKit.cs
new file mode 100644
index 000000000000..e15e0865a8d0
--- /dev/null
+++ b/tests/apitest/src/SceneKit/SceneKit.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.CoreAnimation;
+using MonoMac.SceneKit;
+using CGRect = System.Drawing.RectangleF;
+#else
+using AppKit;
+using Foundation;
+using CoreAnimation;
+using CoreGraphics;
+using SceneKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SceneKitTests // Generic one off tests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureYosemite ();
+ if (Asserts.IsAtLeastElCapitan)
+ Asserts.Ensure64Bit ();
+ }
+
+ [Test]
+ public void SCNGeometrySourceSemantic_ColorKeyTest ()
+ {
+ NSString s = SCNGeometrySourceSemantic.Color;
+ Assert.IsTrue (s != null && s != (NSString)(string.Empty));
+ }
+
+ [Test]
+ public void SCNPhysicsTestKeys_SearchModeKeyTest ()
+ {
+ NSString s = SCNPhysicsTestKeys.SearchModeKey;
+ Assert.IsTrue (s != null && s != (NSString)(string.Empty));
+ }
+
+ [Test]
+ public void SCNSceneSourceLoading_AnimationImportPolicyKeyTest ()
+ {
+ NSString s = SCNSceneSourceLoading.AnimationImportPolicyKey;
+ Assert.IsTrue (s != null && s != (NSString)(string.Empty));
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/apitest/src/SearchKit/SearchKitTest.cs b/tests/apitest/src/SearchKit/SearchKitTest.cs
new file mode 100644
index 000000000000..0f7611d2130f
--- /dev/null
+++ b/tests/apitest/src/SearchKit/SearchKitTest.cs
@@ -0,0 +1,154 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using SearchKit;
+
+namespace apitest {
+
+ [TestFixture]
+ public class SearchKitTests {
+ string path = "/tmp/my.index";
+
+ [SetUp]
+ public void Setup ()
+ {
+ SKIndex.LoadDefaultExtractorPlugIns ();
+ if (File.Exists (path))
+ File.Delete (path);
+
+ }
+
+ [Test]
+ public void TestCreate ()
+ {
+ var idx = SKIndex.CreateWithUrl (new NSUrl ("file://" + path), "myIndex", SKIndexType.InvertedVector, null);
+ if (idx == null)
+ throw new Exception ();
+
+
+ var d1 = new SKDocument (new NSUrl ("file:///etc/passwd"));
+ var d2 = new SKDocument (new NSUrl ("file:///etc/fstab"));
+ idx.AddDocument (d1, "text/plain", true);
+
+ idx.AddDocumentWithText (d2, "This file contains some text like an Apple and an Orange", true);
+
+ const int max = 10;
+ nint [] ids = new nint [max];
+ float[] scores = new float[max];
+ nint nfound;
+ bool more;
+
+ using (var search = idx.Search ("some", SKSearchOptions.SpaceMeansOr)) {
+ more = search.FindMatches (max, ref ids, ref scores, 1, out nfound);
+ Assert.IsFalse (more);
+
+ for (nint i = 0; i < nfound; i++) {
+ var doc = idx.GetDocument (ids [i]);
+ Assert.IsNotNull (doc, "TestCreate - GetDocument returned null");
+ }
+ }
+
+ using (var search = idx.Search ("some", SKSearchOptions.SpaceMeansOr)) {
+ more = search.FindMatches (max, ref ids, 1, out nfound);
+ for (nint i = 0; i < nfound; i++) {
+ var doc = idx.GetDocument (ids [i]);
+ Console.WriteLine ("Got {0}", doc);
+ }
+ }
+
+ idx.Compact ();
+ idx.Flush ();
+ idx.Close ();
+
+ // Now open
+ idx = SKIndex.FromUrl (new NSUrl ("file://" + path), "myIndex", true);
+ Assert.NotNull (idx);
+
+ }
+
+ [Test]
+ public void TestInMemory ()
+ {
+ var m = new NSMutableData ();
+ var idx = SKIndex.CreateWithMutableData (m, "indexName", SKIndexType.Inverted, null);
+ Assert.NotNull (idx);
+ idx.AddDocumentWithText (new SKDocument (new NSUrl ("file:///etc/passwd")), "These are the contents of the passwd file, well, not really", true);
+ idx.Flush ();
+ idx.Compact ();
+ idx.Close ();
+
+ idx = SKIndex.FromMutableData (m, "indexName");
+ Assert.NotNull (idx);
+ idx.Close ();
+ }
+
+ [Test]
+ public void TestTextAnalysis ()
+ {
+ var m = new NSMutableData ();
+ var properties = new SKTextAnalysis () {
+ StartTermChars = "",
+ EndTermChars = "",
+ TermChars = "\"-_@.'",
+ MinTermLength = 3,
+ StopWords = new NSSet ("all", "and", "its", "it's", "the")
+ };
+
+ var idx = SKIndex.CreateWithMutableData (m, "indexName", SKIndexType.Inverted, properties);
+ Assert.NotNull (idx);
+
+ }
+
+ [Test]
+ public void TestSummary ()
+ {
+ var sum = SKSummary.Create (
+ "Once upon a time, there was a dog that loved to take long walks in the park and enjoyed jumping all around (maybe more so on hot days).\n\n" +
+ "One day he ran into a solid rock in the park and was puzzled by it.\n\n" +
+ "If I cook this rock enough, it will be soft and tasty. I might even get lucky and find some salt.");
+
+ Assert.NotNull (sum);
+ var rankOrder = new nint[10];
+ var sentenceIndex = new nint[10];
+ var paragraphIndex = new nint [10];
+
+ nint n;
+ n = sum.GetSentenceSummaryInfo (10, rankOrder, sentenceIndex, paragraphIndex);
+ Assert.AreEqual (4, n);
+ Assert.AreEqual (2, paragraphIndex[3]); // 4th sentence (index 3) is on the 3rd (index 2) paragraph
+ n = sum.GetSentenceSummaryInfo (10, null, sentenceIndex, paragraphIndex);
+ Assert.AreEqual (4, n);
+ n = sum.GetSentenceSummaryInfo (10, rankOrder, null, paragraphIndex);
+ Assert.AreEqual (4, n);
+ n = sum.GetSentenceSummaryInfo (10, rankOrder, sentenceIndex, null);
+ Assert.AreEqual (4, n);
+ n = sum.GetSentenceSummaryInfo (10, null, null, paragraphIndex);
+ Assert.AreEqual (4, n);
+ n = sum.GetSentenceSummaryInfo (10, null, sentenceIndex, null);
+ Assert.AreEqual (4, n);
+ n = sum.GetSentenceSummaryInfo (10, rankOrder, null, null);
+ Assert.AreEqual (4, n);
+ n = sum.GetSentenceSummaryInfo (10, null, null, null);
+ Assert.AreEqual (4, n);
+
+ n = sum.GetParagraphSummaryInfo (10, rankOrder, paragraphIndex);
+ n = sum.GetParagraphSummaryInfo (10, null, paragraphIndex);
+ n = sum.GetParagraphSummaryInfo (10, rankOrder, null);
+ n = sum.GetParagraphSummaryInfo (10, null, null);
+ var sentence = sum.GetSentence (3);
+ Assert.AreEqual ("I might even get lucky and find some salt.", sentence);
+ var par = sum.GetParagraph (1);
+ Assert.AreEqual ("One day he ran into a solid rock in the park and was puzzled by it.\n", par);
+ var ssum = sum.GetSentenceSummary (1);
+ Assert.NotNull (ssum);
+ var psum = sum.GetParagraphSummary (1);
+ Assert.NotNull (psum);
+ }
+ }
+}
+#endif
diff --git a/tests/apitest/src/SpriteKit/SKPaymentTests.cs b/tests/apitest/src/SpriteKit/SKPaymentTests.cs
new file mode 100644
index 000000000000..5aa414a52592
--- /dev/null
+++ b/tests/apitest/src/SpriteKit/SKPaymentTests.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+#if !XAMCORE_2_0
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.StoreKit;
+using nuint = System.UInt32;
+#else
+using AppKit;
+using Foundation;
+using StoreKit;
+#endif
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SKPaymentTests
+ {
+ [Test]
+ public void SKPayment_PaymentWithProduct ()
+ {
+ SKProduct product = new SKProduct();
+ SKPayment payment = SKPayment.PaymentWithProduct (product);
+ Assert.IsNotNull (payment);
+ }
+ }
+}
+
diff --git a/tests/apitest/src/SpriteKit/SKScene.cs b/tests/apitest/src/SpriteKit/SKScene.cs
new file mode 100644
index 000000000000..1468bff902f9
--- /dev/null
+++ b/tests/apitest/src/SpriteKit/SKScene.cs
@@ -0,0 +1,52 @@
+#if XAMCORE_2_0
+using System;
+using System.Threading.Tasks;
+using NUnit.Framework;
+
+using AppKit;
+using Foundation;
+using CoreAnimation;
+using CoreGraphics;
+using SpriteKit;
+
+namespace Xamarin.Mac.Tests
+{
+ [TestFixture]
+ public class SKSceneTests
+ {
+ [SetUp]
+ public void SetUp ()
+ {
+ Asserts.EnsureMavericks ();
+ }
+
+ [Test]
+ public void SKScene_InitWithSize ()
+ {
+ if (IntPtr.Size != 8) // SpriteKit is 64-bit only on mac
+ return;
+
+ SKNode c = new SKNode ();
+ //SKScene c = new SKScene (new CGSize (50, 50));
+ Assert.IsNotNull (c);
+ }
+
+ [Test]
+ public void SKScene_InitWithSizeSuper ()
+ {
+ if (IntPtr.Size != 8) // SpriteKit is 64-bit only on mac
+ return;
+
+ MyScene c = new MyScene (new CGSize (50, 50));
+ Assert.IsNotNull (c);
+ }
+
+ class MyScene : SKScene
+ {
+ public MyScene (CGSize size) : base (size)
+ {
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/tests/bcl-test/.gitignore b/tests/bcl-test/.gitignore
new file mode 100644
index 000000000000..6e4386e149a3
--- /dev/null
+++ b/tests/bcl-test/.gitignore
@@ -0,0 +1,3 @@
+*/*.csproj
+*/*.sln
+*.exe
\ No newline at end of file
diff --git a/tests/bcl-test/AppDelegate.cs b/tests/bcl-test/AppDelegate.cs
new file mode 100644
index 000000000000..3e84e45aefad
--- /dev/null
+++ b/tests/bcl-test/AppDelegate.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+using MonoTouch.NUnit.UI;
+using NUnit.Framework.Internal.Filters;
+
+#if !__WATCHOS__
+
+namespace BCL.Tests
+{
+ // The UIApplicationDelegate for the application. This class is responsible for launching the
+ // User Interface of the application, as well as listening (and optionally responding) to
+ // application events from iOS.
+ [Register ("AppDelegate")]
+ public partial class AppDelegate : UIApplicationDelegate
+ {
+ // class-level declarations
+ UIWindow window;
+ TouchRunner runner;
+
+ //
+ // This method is invoked when the application has loaded and is ready to run. In this
+ // method you should instantiate the window, load the UI into it and then make the window
+ // visible.
+ //
+ // You have 17 seconds to return from this method, or iOS will terminate your application.
+ //
+ public override bool FinishedLaunching (UIApplication app, NSDictionary options)
+ {
+ // create a new window instance based on the screen size
+ window = new UIWindow (UIScreen.MainScreen.Bounds);
+ runner = new TouchRunner (window);
+ runner.Filter = new NotFilter (new CategoryExpression ("MobileNotWorking,NotOnMac,NotWorking,ValueAdd,CAS,InetAccess,NotWorkingInterpreter").Filter);
+
+ // register every tests included in the main application/assembly
+ runner.Add (System.Reflection.Assembly.GetExecutingAssembly ());
+
+ window.RootViewController = new UINavigationController (runner.GetViewController ());
+
+ // make the window visible
+ window.MakeKeyAndVisible ();
+
+ return true;
+ }
+ }
+}
+#endif // !__WATCHOS__
diff --git a/tests/bcl-test/Info.plist b/tests/bcl-test/Info.plist
new file mode 100644
index 000000000000..38994b08cb21
--- /dev/null
+++ b/tests/bcl-test/Info.plist
@@ -0,0 +1,31 @@
+
+
+
+
+ CFBundleDisplayName
+ BclTest
+ CFBundleIdentifier
+ com.xamarin.bcl-test
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+
+
diff --git a/tests/bcl-test/Main.cs b/tests/bcl-test/Main.cs
new file mode 100644
index 000000000000..81470ec2ca7f
--- /dev/null
+++ b/tests/bcl-test/Main.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace BCL.Tests
+{
+#if !__WATCHOS__
+ public class Application
+ {
+ // This is the main entry point of the application.
+ static void Main (string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main (args, null, "AppDelegate");
+ }
+ }
+#endif
+
+ public class TestRuntime
+ {
+ [DllImport ("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
+ static extern IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector);
+
+ [DllImport ("/usr/lib/system/libdyld.dylib")]
+ static extern int dyld_get_program_sdk_version ();
+
+ public const string BuildVersion_iOS7_DP3 = "11D5134c";
+ public const string BuildVersion_iOS8_Beta1 = "12A4265u";
+
+ public static string GetiOSBuildVersion ()
+ {
+#if __WATCHOS__
+ throw new Exception ("Can't get iOS build version on watchOS");
+#else
+ return NSString.FromHandle (IntPtr_objc_msgSend (UIDevice.CurrentDevice.Handle, Selector.GetHandle ("buildVersion")));
+#endif
+ }
+
+ public static Version GetSDKVersion ()
+ {
+ var v = dyld_get_program_sdk_version ();
+ var major = v >> 16;
+ var minor = (v >> 8) & 0xFF;
+ var build = v & 0xFF;
+ return new Version (major, minor, build);
+ }
+
+ // This method returns true if:
+ // system version >= specified version
+ // AND
+ // sdk version >= specified version
+ public static bool CheckSystemAndSDKVersion (int major, int minor)
+ {
+#if __WATCHOS__
+ throw new Exception ("Can't get iOS System/SDK version on watchOS");
+#else
+ if (!UIDevice.CurrentDevice.CheckSystemVersion (major, minor))
+ return false;
+#endif
+
+ // Check if the SDK version we're built includes the version we're checking for
+ // We don't want to execute iOS7 tests on an iOS7 device when built with the iOS6 SDK.
+ return CheckSDKVersion (major, minor);
+ }
+
+ public static bool CheckSystemVersion (int major, int minor)
+ {
+#if __WATCHOS__
+ throw new Exception ("Can't get iOS System/SDK version on watchOS");
+#else
+ return UIDevice.CurrentDevice.CheckSystemVersion (major, minor);
+#endif
+ }
+
+ public static bool CheckSDKVersion (int major, int minor)
+ {
+#if __WATCHOS__
+ throw new Exception ("Can't get iOS SDK version on watchOS");
+#else
+ if (Runtime.Arch == Arch.SIMULATOR || !CheckSystemVersion (6, 0)) {
+ // dyld_get_program_sdk_version was introduced with iOS 6.0, so don't do the SDK check on older deviecs.
+ return true; // dyld_get_program_sdk_version doesn't return what we're looking for on the mac.
+ }
+#endif
+
+ var sdk = GetSDKVersion ();
+ if (sdk.Major > major)
+ return true;
+ if (sdk.Major == major && sdk.Minor >= minor)
+ return true;
+ return false;
+ }
+ }
+}
diff --git a/tests/bcl-test/Make.frag b/tests/bcl-test/Make.frag
new file mode 100644
index 000000000000..9282a04c0b7d
--- /dev/null
+++ b/tests/bcl-test/Make.frag
@@ -0,0 +1,43 @@
+
+ifneq ($(RELEASE),)
+CONFIG=Release
+else
+CONFIG=Debug
+endif
+
+all: build-dev
+
+build-dev:
+ $(MAKE) -C ../.. build-ios-devunified-$(LIB)
+
+clean-dev:
+ $(MAKE) -C ../.. clean-ios-devunified-$(LIB)
+
+install-dev:
+ $(MAKE) -C ../.. install-ios-devunified-$(LIB)
+
+exec-dev:
+ $(MAKE) -C ../.. exec-ios-devunified-$(LIB)
+
+debug-dev:
+ fruitstrap debug --bundle bin/iPhone/$(CONFIG)/$(shell echo $(LIB) | sed 's/-//g' | sed 's/\.//g').app --args "-app-arg:-autostart"
+
+build: build-dev
+clean: clean-dev
+install: install-dev
+exec: exec-dev
+run: debug-dev
+
+logdev:
+ $(MAKE) -C ../.. logdev
+
+build-%:
+ $(MAKE) -C ../.. $@-$(LIB)
+run-%:
+ $(MAKE) -C ../.. $@-$(LIB)
+exec-%:
+ $(MAKE) -C ../.. $@-$(LIB)
+install-%:
+ $(MAKE) -C ../.. $@-$(LIB)
+clean-%:
+ $(MAKE) -C ../.. $@-$(LIB)
diff --git a/tests/bcl-test/Mono.Data.Sqlite/Info.plist b/tests/bcl-test/Mono.Data.Sqlite/Info.plist
new file mode 100644
index 000000000000..9a97f56e3156
--- /dev/null
+++ b/tests/bcl-test/Mono.Data.Sqlite/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.monodatasqlitetests
+
+
diff --git a/tests/bcl-test/Mono.Data.Sqlite/Mono.Data.Sqlite.csproj.template b/tests/bcl-test/Mono.Data.Sqlite/Mono.Data.Sqlite.csproj.template
new file mode 100644
index 000000000000..4ab1869aff7c
--- /dev/null
+++ b/tests/bcl-test/Mono.Data.Sqlite/Mono.Data.Sqlite.csproj.template
@@ -0,0 +1,140 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {1ADF4F27-7610-4501-A62E-1157273AED7E}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ MonoDataSqliteTests
+ 168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ cjk
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ cjk
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
+
+ Resources\Resources.es-ES.resx
+ Resources.es-ES.resources
+
+
+ Resources\Resources.nn-NO.resx
+ Resources.nn-NO.resources
+
+
+ Resources\Resources.resx
+ Resources.resources
+
+
+
diff --git a/tests/bcl-test/Mono.Security/Info.plist b/tests/bcl-test/Mono.Security/Info.plist
new file mode 100644
index 000000000000..7f61d7e108fa
--- /dev/null
+++ b/tests/bcl-test/Mono.Security/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.monosecuritytests
+
+
diff --git a/tests/bcl-test/Mono.Security/Makefile b/tests/bcl-test/Mono.Security/Makefile
new file mode 100644
index 000000000000..a8a75083e94c
--- /dev/null
+++ b/tests/bcl-test/Mono.Security/Makefile
@@ -0,0 +1,4 @@
+
+LIB=Mono.Security
+
+include ../Make.frag
diff --git a/tests/bcl-test/Mono.Security/Mono.Security.csproj.template b/tests/bcl-test/Mono.Security/Mono.Security.csproj.template
new file mode 100644
index 000000000000..3fc411d9c6ba
--- /dev/null
+++ b/tests/bcl-test/Mono.Security/Mono.Security.csproj.template
@@ -0,0 +1,126 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {5023D584-1A32-4917-90C5-A641C800230C}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ MonoSecurityTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+ Assert.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.ComponentModel.DataAnnotations/Info.plist b/tests/bcl-test/System.ComponentModel.DataAnnotations/Info.plist
new file mode 100644
index 000000000000..745c339435c9
--- /dev/null
+++ b/tests/bcl-test/System.ComponentModel.DataAnnotations/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemcomponentmodeldataannotationstests
+
+
diff --git a/tests/bcl-test/System.ComponentModel.DataAnnotations/Makefile b/tests/bcl-test/System.ComponentModel.DataAnnotations/Makefile
new file mode 100644
index 000000000000..01e08c068e45
--- /dev/null
+++ b/tests/bcl-test/System.ComponentModel.DataAnnotations/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.ComponentModel.DataAnnotations
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj.template b/tests/bcl-test/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj.template
new file mode 100644
index 000000000000..9e111572341f
--- /dev/null
+++ b/tests/bcl-test/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj.template
@@ -0,0 +1,124 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {3DF294C6-91F1-407B-8A0C-AFACC7C1BDE8}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemComponentModelDataAnnotationsTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+ ..\..\..\..\..\usr\lib\mono\2.1\System.ComponentModel.DataAnnotations.dll
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Core/Info.plist b/tests/bcl-test/System.Core/Info.plist
new file mode 100644
index 000000000000..4936a373aa3c
--- /dev/null
+++ b/tests/bcl-test/System.Core/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemcoretests
+
+
diff --git a/tests/bcl-test/System.Core/Makefile b/tests/bcl-test/System.Core/Makefile
new file mode 100644
index 000000000000..132099123f30
--- /dev/null
+++ b/tests/bcl-test/System.Core/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Core
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Core/System.Core.csproj.template b/tests/bcl-test/System.Core/System.Core.csproj.template
new file mode 100644
index 000000000000..062b42d8ada2
--- /dev/null
+++ b/tests/bcl-test/System.Core/System.Core.csproj.template
@@ -0,0 +1,122 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {FBC970AA-8234-4905-B559-BD3F32A63C04}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemCoreTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Data/Info.plist b/tests/bcl-test/System.Data/Info.plist
new file mode 100644
index 000000000000..8232dc8bd8eb
--- /dev/null
+++ b/tests/bcl-test/System.Data/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemdatatests
+
+
diff --git a/tests/bcl-test/System.Data/Makefile b/tests/bcl-test/System.Data/Makefile
new file mode 100644
index 000000000000..caeea80d1e3f
--- /dev/null
+++ b/tests/bcl-test/System.Data/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Data
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Data/System.Data.csproj.template b/tests/bcl-test/System.Data/System.Data.csproj.template
new file mode 100644
index 000000000000..9884de12caa1
--- /dev/null
+++ b/tests/bcl-test/System.Data/System.Data.csproj.template
@@ -0,0 +1,269 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {BEF0140A-A6A6-4074-B55F-03856A6B5862}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemDataTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+ west
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+ west
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+ west
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+ west
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+ west
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+ west
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+ Assert.cs
+
+
+
+#FILES#
+
+
+
+
+ Test\System.Data\binserialize\BS-tb1.bin
+
+
+ Test\System.Data\binserialize\BS-tb2.bin
+
+
+ Test\System.Data\binserialize\BS-tb3.bin
+
+
+ Test\System.Data\binserialize\BS-tb4.bin
+
+
+ Test\System.Data\binserialize\BS-tb5.bin
+
+
+ Test\System.Data\store.xsd
+
+
+ Test\System.Data\store2.xsd
+
+
+ Test\System.Data\store3.xsd
+
+
+ Test\System.Data\store4.xsd
+
+
+ Test\System.Data\schemas\b582732.xml
+
+
+ Test\System.Data\schemas\bug77248.xsd
+
+
+ Test\System.Data\schemas\Items.xsd
+
+
+ Test\System.Data\schemas\test001.xsd
+
+
+ Test\System.Data\schemas\test002.xsd
+
+
+ Test\System.Data\schemas\test003.xsd
+
+
+ Test\System.Data\schemas\test004.xsd
+
+
+ Test\System.Data\schemas\test005.xsd
+
+
+ Test\System.Data\schemas\test006.xsd
+
+
+ Test\System.Data\schemas\test007.xsd
+
+
+ Test\System.Data\schemas\test008.xsd
+
+
+ Test\System.Data\schemas\test009.xsd
+
+
+ Test\System.Data\schemas\test010.xsd
+
+
+ Test\System.Data\schemas\test011.xsd
+
+
+ Test\System.Data\schemas\test012.xsd
+
+
+ Test\System.Data\schemas\test013.xsd
+
+
+ Test\System.Data\schemas\test014.xsd
+
+
+ Test\System.Data\schemas\test015.xsd
+
+
+ Test\System.Data\schemas\test016.xsd
+
+
+ Test\System.Data\schemas\test017.xsd
+
+
+ Test\System.Data\schemas\test101.xsd
+
+
+ Test\System.Data\schemas\test102.xsd
+
+
+ Test\System.Data\schemas\test103.xsd
+
+
+ Test\System.Data\region.xml
+
+
+ Test\System.Data\own_schema.xsd
+
+
+ Test\System.Data\own_schema1.xsd
+
+
+ Test\System.Data\own_schema2.xsd
+
+
+ Test\System.Data\TypedDataSet.xml
+
+
+ Test\System.Xml\region.xml
+
+
+ Test\System.Xml\region.xsd
+
+
+ Test\System.Xml\store.xsd
+
+
+ Test\Mono.Data.SqlExpressions\dateComparisonTest.xml
+
+
+ Test\System.Data\TestMerge1.xml
+
+
+ Test\System.Xml\2books.xml
+
+
+ Test\System.Data\TestReadXmlSchema1.xml
+
+
+ Test\System.Data\TestReadXml1.xml
+
+
+
diff --git a/tests/bcl-test/System.Json/Info.plist b/tests/bcl-test/System.Json/Info.plist
new file mode 100644
index 000000000000..608d9fe7e8bf
--- /dev/null
+++ b/tests/bcl-test/System.Json/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemjsontests
+
+
diff --git a/tests/bcl-test/System.Json/Makefile b/tests/bcl-test/System.Json/Makefile
new file mode 100644
index 000000000000..875f7ad410a6
--- /dev/null
+++ b/tests/bcl-test/System.Json/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Json
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Json/System.Json.csproj.template b/tests/bcl-test/System.Json/System.Json.csproj.template
new file mode 100644
index 000000000000..91112c091c32
--- /dev/null
+++ b/tests/bcl-test/System.Json/System.Json.csproj.template
@@ -0,0 +1,123 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {5FF294C6-91F1-407B-8A0C-AFACC7C1BDE8}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemJsonTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Net.Http/Info.plist b/tests/bcl-test/System.Net.Http/Info.plist
new file mode 100644
index 000000000000..eb8c2ab014d2
--- /dev/null
+++ b/tests/bcl-test/System.Net.Http/Info.plist
@@ -0,0 +1,35 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemnethttptests
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+
+
diff --git a/tests/bcl-test/System.Net.Http/Makefile b/tests/bcl-test/System.Net.Http/Makefile
new file mode 100644
index 000000000000..77607fcbba16
--- /dev/null
+++ b/tests/bcl-test/System.Net.Http/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Net.Http
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Net.Http/System.Net.Http.csproj.template b/tests/bcl-test/System.Net.Http/System.Net.Http.csproj.template
new file mode 100644
index 000000000000..6250c37953fc
--- /dev/null
+++ b/tests/bcl-test/System.Net.Http/System.Net.Http.csproj.template
@@ -0,0 +1,125 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {D7212E3D-CD1B-4E58-A11D-C7B7898168AA}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemNetHttpTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Net.Http/System.Net.Http/CFNetworkHandlerTest.cs b/tests/bcl-test/System.Net.Http/System.Net.Http/CFNetworkHandlerTest.cs
new file mode 100644
index 000000000000..ba90d8f02953
--- /dev/null
+++ b/tests/bcl-test/System.Net.Http/System.Net.Http/CFNetworkHandlerTest.cs
@@ -0,0 +1,754 @@
+//
+// CFNetworkHandlerTest.cs
+//
+// Authors:
+// Marek Safar
+//
+// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if !__WATCHOS__
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using NUnit.Framework;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Net;
+using System.Linq;
+using System.IO;
+
+namespace MonoTests.System.Net.Http
+{
+ [TestFixture]
+ public class CFNetworkHandlerTest
+ {
+ class HttpMessageHandlerMock : CFNetworkHandler
+ {
+ public Func> OnSend;
+ public Func> OnSendFull;
+
+ public HttpMessageHandlerMock ()
+ {
+ }
+
+ protected override Task SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ if (OnSend != null)
+ return OnSend (request);
+
+ if (OnSendFull != null)
+ return OnSendFull (request, cancellationToken);
+
+ Assert.Fail ("Send");
+ return null;
+ }
+ }
+
+ const int WaitTimeout = 2500;
+
+ string port, TestHost, LocalServer;
+
+ HttpClient client;
+
+ [SetUp]
+ public void SetupFixture ()
+ {
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
+ port = "810";
+ } else {
+ port = "8810";
+ }
+
+ TestHost = "localhost:" + port;
+ LocalServer = string.Format ("http://{0}/", TestHost);
+ client = new HttpClient (new CFNetworkHandler ());
+ }
+
+ [Test]
+ public void Ctor_Default ()
+ {
+ Assert.IsNull (client.BaseAddress, "#1");
+ Assert.IsNotNull (client.DefaultRequestHeaders, "#2"); // TODO: full check
+ Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#3");
+ Assert.AreEqual (TimeSpan.FromSeconds (100), client.Timeout, "#4");
+ }
+
+ [Test]
+ public void CancelPendingRequests ()
+ {
+ var mh = new HttpMessageHandlerMock ();
+
+ var client = new HttpClient (mh);
+ var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+ var mre = new ManualResetEvent (false);
+
+ mh.OnSendFull = (l, c) => {
+ mre.Set ();
+ Assert.IsTrue (c.WaitHandle.WaitOne (1000), "#20");
+ Assert.IsTrue (c.IsCancellationRequested, "#21");
+ mre.Set ();
+ return Task.FromResult (new HttpResponseMessage ());
+ };
+
+ var t = Task.Factory.StartNew (() => {
+ client.SendAsync (request).Wait (WaitTimeout);
+ });
+
+ Assert.IsTrue (mre.WaitOne (500), "#1");
+ mre.Reset ();
+ client.CancelPendingRequests ();
+ Assert.IsTrue (t.Wait (500), "#2");
+
+ request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+ mh.OnSendFull = (l, c) => {
+ Assert.IsFalse (c.IsCancellationRequested, "#30");
+ return Task.FromResult (new HttpResponseMessage ());
+ };
+
+ client.SendAsync (request).Wait (WaitTimeout);
+ }
+
+ [Test]
+ public void CancelPendingRequests_BeforeSend ()
+ {
+ var ct = new CancellationTokenSource ();
+ ct.Cancel ();
+ var rr = CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken (), ct.Token);
+
+
+ var mh = new HttpMessageHandlerMock ();
+
+ var client = new HttpClient (mh);
+ var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+ client.CancelPendingRequests ();
+
+ mh.OnSendFull = (l, c) => {
+ Assert.IsFalse (c.IsCancellationRequested, "#30");
+ return Task.FromResult (new HttpResponseMessage ());
+ };
+
+ client.SendAsync (request).Wait (WaitTimeout);
+
+ request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+ client.SendAsync (request).Wait (WaitTimeout);
+ }
+
+ [Test]
+ public void Properties ()
+ {
+ client.BaseAddress = null;
+ client.MaxResponseContentBufferSize = int.MaxValue;
+ client.Timeout = Timeout.InfiniteTimeSpan;
+
+ Assert.IsNull (client.BaseAddress, "#1");
+ Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#2");
+ Assert.AreEqual (Timeout.InfiniteTimeSpan, client.Timeout, "#3");
+ }
+
+ [Test]
+ public void Properties_Invalid ()
+ {
+ try {
+ client.MaxResponseContentBufferSize = 0;
+ Assert.Fail ("#1");
+ } catch (ArgumentOutOfRangeException) {
+ }
+
+ try {
+ client.Timeout = TimeSpan.MinValue;
+ Assert.Fail ("#2");
+ } catch (ArgumentOutOfRangeException) {
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send ()
+ {
+ var mh = new HttpMessageHandlerMock ();
+
+ var client = new HttpClient (mh);
+ client.BaseAddress = new Uri ("http://xamarin.com");
+ var request = new HttpRequestMessage ();
+ var response = new HttpResponseMessage ();
+
+ mh.OnSend = l => {
+ Assert.AreEqual (l, request, "#2");
+ Assert.AreEqual (client.BaseAddress, l.RequestUri, "#2");
+ return Task.FromResult (response);
+ };
+
+ Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_DefaultRequestHeaders ()
+ {
+ var mh = new HttpMessageHandlerMock ();
+
+ var client = new HttpClient (mh);
+ client.DefaultRequestHeaders.Referrer = new Uri ("http://google.com");
+
+ var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+ var response = new HttpResponseMessage ();
+
+ mh.OnSend = l => {
+ Assert.AreEqual (client.DefaultRequestHeaders.Referrer, l.Headers.Referrer, "#2");
+ Assert.IsNotNull (l.Headers.Referrer, "#3");
+ return Task.FromResult (response);
+ };
+
+ Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_Default ()
+ {
+ bool? failed = null;
+ var listener = CreateListener (l => {
+ try {
+ var request = l.Request;
+
+ Assert.IsNull (request.AcceptTypes, "#1");
+ Assert.AreEqual (0, request.ContentLength64, "#2");
+ Assert.IsNull (request.ContentType, "#3");
+ Assert.AreEqual (0, request.Cookies.Count, "#4");
+ Assert.IsFalse (request.HasEntityBody, "#5");
+ Assert.AreEqual (TestHost, request.Headers["Host"], "#6b");
+ Assert.AreEqual ("GET", request.HttpMethod, "#7");
+ Assert.IsFalse (request.IsAuthenticated, "#8");
+ Assert.IsTrue (request.IsLocal, "#9");
+ Assert.IsFalse (request.IsSecureConnection, "#10");
+ Assert.IsFalse (request.IsWebSocketRequest, "#11");
+ Assert.IsTrue (request.KeepAlive, "#12");
+ Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
+ Assert.IsNull (request.ServiceName, "#14");
+ Assert.IsNull (request.UrlReferrer, "#15");
+ Assert.IsNull (request.UserAgent, "#16");
+ Assert.IsNull (request.UserLanguages, "#17");
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ });
+
+ try {
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+ Assert.AreEqual (false, failed, "#102");
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_Version_1_0 ()
+ {
+ bool? failed = null;
+
+ var listener = CreateListener (l => {
+ try {
+ var request = l.Request;
+
+ Assert.IsNull (request.AcceptTypes, "#1");
+ Assert.AreEqual (0, request.ContentLength64, "#2");
+ Assert.IsNull (request.ContentType, "#3");
+ Assert.AreEqual (0, request.Cookies.Count, "#4");
+ Assert.IsFalse (request.HasEntityBody, "#5");
+ Assert.AreEqual (1, request.Headers.Count, "#6");
+ Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
+ Assert.AreEqual ("GET", request.HttpMethod, "#7");
+ Assert.IsFalse (request.IsAuthenticated, "#8");
+ Assert.IsTrue (request.IsLocal, "#9");
+ Assert.IsFalse (request.IsSecureConnection, "#10");
+ Assert.IsFalse (request.IsWebSocketRequest, "#11");
+ Assert.IsFalse (request.KeepAlive, "#12");
+ Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
+ Assert.IsNull (request.ServiceName, "#14");
+ Assert.IsNull (request.UrlReferrer, "#15");
+ Assert.IsNull (request.UserAgent, "#16");
+ Assert.IsNull (request.UserLanguages, "#17");
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ });
+
+ try {
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ request.Version = HttpVersion.Version10;
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+ Assert.AreEqual (false, failed, "#102");
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_ClientHandlerSettings ()
+ {
+ bool? failed = null;
+
+ var listener = CreateListener (l => {
+ var request = l.Request;
+
+ try {
+ Assert.IsNull (request.AcceptTypes, "#1");
+ Assert.AreEqual (0, request.ContentLength64, "#2");
+ Assert.IsNull (request.ContentType, "#3");
+ Assert.AreEqual (1, request.Cookies.Count, "#4");
+ Assert.AreEqual (new Cookie ("mycookie", "vv"), request.Cookies[0], "#4a");
+ Assert.IsFalse (request.HasEntityBody, "#5");
+ Assert.AreEqual (4, request.Headers.Count, "#6");
+ Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
+ Assert.AreEqual ("gzip", request.Headers["Accept-Encoding"], "#6b");
+ Assert.AreEqual ("mycookie=vv", request.Headers["Cookie"], "#6c");
+ Assert.AreEqual ("GET", request.HttpMethod, "#7");
+ Assert.IsFalse (request.IsAuthenticated, "#8");
+ Assert.IsTrue (request.IsLocal, "#9");
+ Assert.IsFalse (request.IsSecureConnection, "#10");
+ Assert.IsFalse (request.IsWebSocketRequest, "#11");
+ Assert.IsTrue (request.KeepAlive, "#12");
+ Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
+ Assert.IsNull (request.ServiceName, "#14");
+ Assert.IsNull (request.UrlReferrer, "#15");
+ Assert.IsNull (request.UserAgent, "#16");
+ Assert.IsNull (request.UserLanguages, "#17");
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ });
+
+ try {
+ var chandler = new CFNetworkHandler ();
+ chandler.AllowAutoRedirect = true;
+// chandler.AutomaticDecompression = DecompressionMethods.GZip;
+// chandler.MaxAutomaticRedirections = 33;
+// chandler.MaxRequestContentBufferSize = 5555;
+// chandler.PreAuthenticate = true;
+// chandler.CookieContainer.Add (new Uri (LocalServer), new Cookie ( "mycookie", "vv"));
+// chandler.UseCookies = true;
+// chandler.UseDefaultCredentials = true;
+// chandler.Proxy = new WebProxy ("ee");
+// chandler.UseProxy = true;
+
+ var client = new HttpClient (chandler);
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ request.Version = HttpVersion.Version10;
+ request.Headers.Add ("Keep-Alive", "false");
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+ Assert.AreEqual (false, failed, "#102");
+ } finally {
+ listener.Abort ();
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_CustomHeaders ()
+ {
+ bool? failed = null;
+
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ try {
+ Assert.AreEqual ("vv", request.Headers["aa"], "#1");
+
+ var response = l.Response;
+ response.Headers.Add ("rsp", "rrr");
+ response.Headers.Add ("upgrade", "vvvvaa");
+ response.Headers.Add ("Date", "aa");
+ response.Headers.Add ("cache-control", "audio");
+
+ response.StatusDescription = "test description";
+ response.ProtocolVersion = HttpVersion.Version10;
+ response.SendChunked = true;
+ response.RedirectLocation = "w3.org";
+
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ });
+
+ try {
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+
+ IEnumerable values;
+ Assert.IsTrue (response.Headers.TryGetValues ("rsp", out values), "#102");
+ Assert.AreEqual ("rrr", values.First (), "#102a");
+
+ Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#103");
+ Assert.AreEqual ("chunked", values.First (), "#103a");
+ Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#103b");
+
+ Assert.IsTrue (response.Headers.TryGetValues ("Date", out values), "#104");
+ Assert.AreEqual (1, values.Count (), "#104b");
+ // .NET overwrites Date, Mono does not
+ // Assert.IsNotNull (response.Headers.Date, "#104c");
+
+ Assert.AreEqual (new ProductHeaderValue ("vvvvaa"), response.Headers.Upgrade.First (), "#105");
+
+ Assert.AreEqual ("audio", response.Headers.CacheControl.Extensions.First ().Name, "#106");
+
+ Assert.AreEqual ("w3.org", response.Headers.Location.OriginalString, "#107");
+
+ Assert.AreEqual ("test description", response.ReasonPhrase, "#110");
+ Assert.AreEqual (HttpVersion.Version11, response.Version, "#111");
+
+ Assert.AreEqual (false, failed, "#112");
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_Content ()
+ {
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ l.Response.OutputStream.WriteByte (55);
+ l.Response.OutputStream.WriteByte (75);
+ });
+
+ try {
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("7K", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+
+ IEnumerable values;
+ Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#102");
+ Assert.AreEqual ("chunked", values.First (), "#102a");
+ Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#102b");
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_Content_MaxResponseContentBufferSize ()
+ {
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ var b = new byte[4000];
+ l.Response.OutputStream.Write (b, 0, b.Length);
+ });
+
+ try {
+ client.MaxResponseContentBufferSize = 1000;
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual (4000, response.Content.ReadAsStringAsync ().Result.Length, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
+ {
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ var b = new byte[4000];
+ l.Response.OutputStream.Write (b, 0, b.Length);
+ });
+
+ try {
+ client.MaxResponseContentBufferSize = 1000;
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+
+ try {
+ client.SendAsync (request, HttpCompletionOption.ResponseContentRead).Wait (WaitTimeout);
+ Assert.Fail ("#2");
+ } catch (AggregateException e) {
+ Assert.IsTrue (e.InnerException is HttpRequestException, "#3");
+ }
+
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Complete_Error ()
+ {
+ var listener = CreateListener (l => {
+ var response = l.Response;
+ response.StatusCode = 500;
+ });
+
+ try {
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.InternalServerError, response.StatusCode, "#101");
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Content_Get ()
+ {
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ l.Response.OutputStream.WriteByte (72);
+ });
+
+ try {
+ var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+ var response = client.SendAsync (r).Result;
+
+ Assert.AreEqual ("H", response.Content.ReadAsStringAsync ().Result);
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Content_Put ()
+ {
+ bool passed = false;
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ passed = 7 == request.ContentLength64;
+ passed &= request.ContentType == "text/plain; charset=utf-8";
+ passed &= request.InputStream.ReadByte () == 'm';
+ });
+
+ try {
+ var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
+ r.Content = new StringContent ("my text");
+ var response = client.SendAsync (r).Result;
+
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
+ Assert.IsTrue (passed, "#2");
+ } finally {
+ listener.Abort ();
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void Send_Timeout ()
+ {
+ var mh = new HttpMessageHandlerMock ();
+
+ client.Timeout = TimeSpan.FromMilliseconds (100);
+ var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+ var response = new HttpResponseMessage ();
+
+ mh.OnSendFull = (l, c) => {
+ Assert.IsTrue (c.WaitHandle.WaitOne (500), "#2");
+ return Task.FromResult (response);
+ };
+
+ Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
+ }
+
+ [Test]
+ public void Send_Invalid ()
+ {
+ try {
+ client.SendAsync (null).Wait (WaitTimeout);
+ Assert.Fail ("#1");
+ } catch (ArgumentNullException) {
+ }
+
+ try {
+ var request = new HttpRequestMessage ();
+ client.SendAsync (request).Wait (WaitTimeout);
+ Assert.Fail ("#2");
+ } catch (InvalidOperationException) {
+ }
+ }
+
+ [Test]
+ public void Send_InvalidHandler ()
+ {
+ var mh = new HttpMessageHandlerMock ();
+
+ var client = new HttpClient (mh);
+ client.BaseAddress = new Uri ("http://xamarin.com");
+ var request = new HttpRequestMessage ();
+
+ mh.OnSend = l => {
+ Assert.AreEqual (l, request, "#1");
+ return null;
+ };
+
+ try {
+ // Broken by design
+ client.SendAsync (request).Wait (WaitTimeout);
+ Assert.Fail ("#2");
+ } catch (Exception) {
+ }
+ }
+
+ [Test]
+ public void Send_SameMessage ()
+ {
+ var mh = new HttpMessageHandlerMock ();
+
+ var client = new HttpClient (mh);
+ var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
+
+ mh.OnSend = l => Task.FromResult (new HttpResponseMessage ());
+
+ client.SendAsync (request).Wait (WaitTimeout);
+ try {
+ client.SendAsync (request).Wait (WaitTimeout);
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException) {
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void GetString_RelativeUri ()
+ {
+ client.BaseAddress = new Uri ("http://en.wikipedia.org/wiki/");
+ var uri = new Uri ("Computer", UriKind.Relative);
+
+ Assert.That (client.GetStringAsync (uri).Result != null);
+ Assert.That (client.GetStringAsync ("Computer").Result != null);
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void GetString_Many ()
+ {
+ var t1 = client.GetStringAsync ("http://www.google.com");
+ var t2 = client.GetStringAsync ("http://www.google.com");
+ Assert.IsTrue (Task.WaitAll (new [] { t1, t2 }, WaitTimeout));
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void GetByteArray_ServerError ()
+ {
+ var listener = CreateListener (l => {
+ var response = l.Response;
+ response.StatusCode = 500;
+ l.Response.OutputStream.WriteByte (72);
+ });
+
+ try {
+ try {
+ client.GetByteArrayAsync (LocalServer).Wait (WaitTimeout);
+ Assert.Fail ("#1");
+ } catch (AggregateException e) {
+ Assert.IsTrue (e.InnerException is HttpRequestException , "#2");
+ }
+ } finally {
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ [Ignore ("Blocks main loop")]
+ public void DisallowAutoRedirect ()
+ {
+ var listener = CreateListener (l => {
+ var request = l.Request;
+ var response = l.Response;
+
+ response.StatusCode = (int)HttpStatusCode.Moved;
+ response.RedirectLocation = "http://xamarin.com/";
+ });
+
+ try {
+ var chandler = new CFNetworkHandler ();
+ chandler.AllowAutoRedirect = false;
+ var client = new HttpClient (chandler);
+
+ try {
+ client.GetStringAsync (LocalServer).Wait (WaitTimeout);
+ Assert.Fail ("#1");
+ } catch (AggregateException e) {
+ Assert.IsTrue (e.InnerException is HttpRequestException, "#2");
+ }
+ } finally {
+ listener.Abort ();
+ listener.Close ();
+ }
+ }
+
+ HttpListener CreateListener (Action contextAssert)
+ {
+ var l = new HttpListener ();
+ l.Prefixes.Add (string.Format ("http://+:{0}/", port));
+ l.Start ();
+ l.BeginGetContext (ar => {
+ var ctx = l.EndGetContext (ar);
+
+ try {
+ if (contextAssert != null)
+ contextAssert (ctx);
+ } finally {
+ ctx.Response.Close ();
+ }
+ }, null);
+
+ return l;
+ }
+ }
+}
+
+#endif // !__WATCHOS__
diff --git a/tests/bcl-test/System.Numerics/Info.plist b/tests/bcl-test/System.Numerics/Info.plist
new file mode 100644
index 000000000000..b4ca00a106ef
--- /dev/null
+++ b/tests/bcl-test/System.Numerics/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemnumericstests
+
+
diff --git a/tests/bcl-test/System.Numerics/Makefile b/tests/bcl-test/System.Numerics/Makefile
new file mode 100644
index 000000000000..f774e60ecd44
--- /dev/null
+++ b/tests/bcl-test/System.Numerics/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Numerics
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Numerics/System.Numerics.csproj.template b/tests/bcl-test/System.Numerics/System.Numerics.csproj.template
new file mode 100644
index 000000000000..a99e8ce87ced
--- /dev/null
+++ b/tests/bcl-test/System.Numerics/System.Numerics.csproj.template
@@ -0,0 +1,123 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {4EF294C6-91F1-407B-8A0C-AFACC7C1BDE8}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemNumericsTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Runtime.Serialization/Info.plist b/tests/bcl-test/System.Runtime.Serialization/Info.plist
new file mode 100644
index 000000000000..a546401e4b85
--- /dev/null
+++ b/tests/bcl-test/System.Runtime.Serialization/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemruntimeserializationtests
+
+
diff --git a/tests/bcl-test/System.Runtime.Serialization/Makefile b/tests/bcl-test/System.Runtime.Serialization/Makefile
new file mode 100644
index 000000000000..54c940f12950
--- /dev/null
+++ b/tests/bcl-test/System.Runtime.Serialization/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Runtime.Serialization
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Runtime.Serialization/System.Runtime.Serialization.csproj.template b/tests/bcl-test/System.Runtime.Serialization/System.Runtime.Serialization.csproj.template
new file mode 100644
index 000000000000..12b8b8cc9f17
--- /dev/null
+++ b/tests/bcl-test/System.Runtime.Serialization/System.Runtime.Serialization.csproj.template
@@ -0,0 +1,125 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {B86D100D-895B-4510-A5BB-E08F11E82C3C}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemRuntimeSerializationTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.ServiceModel.Web/Info.plist b/tests/bcl-test/System.ServiceModel.Web/Info.plist
new file mode 100644
index 000000000000..c3488d0db2a8
--- /dev/null
+++ b/tests/bcl-test/System.ServiceModel.Web/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemservicemodelwebtests
+
+
diff --git a/tests/bcl-test/System.ServiceModel.Web/Makefile b/tests/bcl-test/System.ServiceModel.Web/Makefile
new file mode 100644
index 000000000000..35777353b82e
--- /dev/null
+++ b/tests/bcl-test/System.ServiceModel.Web/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.ServiceModel.Web
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.ServiceModel.Web/System.ServiceModel.Web.csproj.template b/tests/bcl-test/System.ServiceModel.Web/System.ServiceModel.Web.csproj.template
new file mode 100644
index 000000000000..1cee0a828d9d
--- /dev/null
+++ b/tests/bcl-test/System.ServiceModel.Web/System.ServiceModel.Web.csproj.template
@@ -0,0 +1,125 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {2CF294C6-91F1-407B-8A0C-AFACC7C1BDE8}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemServiceModelWebTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Transactions/Info.plist b/tests/bcl-test/System.Transactions/Info.plist
new file mode 100644
index 000000000000..3677792571b4
--- /dev/null
+++ b/tests/bcl-test/System.Transactions/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemtransactionstests
+
+
diff --git a/tests/bcl-test/System.Transactions/Makefile b/tests/bcl-test/System.Transactions/Makefile
new file mode 100644
index 000000000000..01e92ceef536
--- /dev/null
+++ b/tests/bcl-test/System.Transactions/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Transactions
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Transactions/System.Transactions.csproj.template b/tests/bcl-test/System.Transactions/System.Transactions.csproj.template
new file mode 100644
index 000000000000..f54275325179
--- /dev/null
+++ b/tests/bcl-test/System.Transactions/System.Transactions.csproj.template
@@ -0,0 +1,121 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {A12ED440-8270-4701-A35D-0C3C9E0AA735}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemTransactionsTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Web.Services/Info.plist b/tests/bcl-test/System.Web.Services/Info.plist
new file mode 100644
index 000000000000..6743bb230e3b
--- /dev/null
+++ b/tests/bcl-test/System.Web.Services/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemwebservicestests
+
+
diff --git a/tests/bcl-test/System.Web.Services/Makefile b/tests/bcl-test/System.Web.Services/Makefile
new file mode 100644
index 000000000000..8a09e30f4ef0
--- /dev/null
+++ b/tests/bcl-test/System.Web.Services/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Web.Services
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Web.Services/System.Web.Services.csproj.template b/tests/bcl-test/System.Web.Services/System.Web.Services.csproj.template
new file mode 100644
index 000000000000..edf79eb4b3b1
--- /dev/null
+++ b/tests/bcl-test/System.Web.Services/System.Web.Services.csproj.template
@@ -0,0 +1,130 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {DA061019-04C3-4221-AF04-63F2BFB5DA42}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemWebServicesTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
+
+ Test\System.Web.Services.Description\test2.wsdl
+
+
+ Test\System.Web.Services.Description\test.wsdl
+
+
+
diff --git a/tests/bcl-test/System.Xml.Linq/Info.plist b/tests/bcl-test/System.Xml.Linq/Info.plist
new file mode 100644
index 000000000000..cd80d0cc6e26
--- /dev/null
+++ b/tests/bcl-test/System.Xml.Linq/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemxmllinqtests
+
+
diff --git a/tests/bcl-test/System.Xml.Linq/Makefile b/tests/bcl-test/System.Xml.Linq/Makefile
new file mode 100644
index 000000000000..db238304c3ba
--- /dev/null
+++ b/tests/bcl-test/System.Xml.Linq/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Xml.Linq
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Xml.Linq/System.Xml.Linq.csproj.template b/tests/bcl-test/System.Xml.Linq/System.Xml.Linq.csproj.template
new file mode 100644
index 000000000000..be4494e9877b
--- /dev/null
+++ b/tests/bcl-test/System.Xml.Linq/System.Xml.Linq.csproj.template
@@ -0,0 +1,119 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {DB354193-B05D-471B-BEB8-F6C74DA4C93A}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemXmlLinqTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/System.Xml/Info.plist b/tests/bcl-test/System.Xml/Info.plist
new file mode 100644
index 000000000000..6b9a0e1c4f02
--- /dev/null
+++ b/tests/bcl-test/System.Xml/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemxmltests
+
+
diff --git a/tests/bcl-test/System.Xml/Makefile b/tests/bcl-test/System.Xml/Makefile
new file mode 100644
index 000000000000..c4f01b9b9234
--- /dev/null
+++ b/tests/bcl-test/System.Xml/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System.Xml
+
+include ../Make.frag
diff --git a/tests/bcl-test/System.Xml/System.Xml.csproj.template b/tests/bcl-test/System.Xml/System.Xml.csproj.template
new file mode 100644
index 000000000000..6d43039a08a2
--- /dev/null
+++ b/tests/bcl-test/System.Xml/System.Xml.csproj.template
@@ -0,0 +1,389 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {93268FFB-571C-4402-8899-027A7778D2C0}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemXmlTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
+
+ Test\XmlFiles\xsd\1.xsd
+
+
+ Test\XmlFiles\xsd\2.xsd
+
+
+ Test\XmlFiles\xsd\3.xsd
+
+
+ Test\XmlFiles\xsd\336625.xsd
+
+
+ Test\XmlFiles\xsd\358408.xsd
+
+
+ Test\XmlFiles\xsd\361818-2.xsd
+
+
+ Test\XmlFiles\xsd\361818-3.xsd
+
+
+ Test\XmlFiles\xsd\361818.xsd
+
+
+ Test\XmlFiles\xsd\376395.xml
+
+
+ Test\XmlFiles\xsd\376395.xsd
+
+
+ Test\XmlFiles\xsd\4.xsd
+
+
+ Test\XmlFiles\xsd\422581.xml
+
+
+ Test\XmlFiles\xsd\422581.xsd
+
+
+ Test\XmlFiles\xsd\5.xsd
+
+
+ Test\XmlFiles\xsd\584664a.xml
+
+
+ Test\XmlFiles\xsd\584664a.xsd
+
+
+ Test\XmlFiles\xsd\584664b.xml
+
+
+ Test\XmlFiles\xsd\584664b.xsd
+
+
+ Test\XmlFiles\xsd\6.xsd
+
+
+ Test\XmlFiles\xsd\670945-1.xsd
+
+
+ Test\XmlFiles\xsd\670945-2.xsd
+
+
+ Test\XmlFiles\xsd\77687.xsd
+
+
+ Test\XmlFiles\xsd\77687inc.xsd
+
+
+ Test\XmlFiles\xsd\78985.xml
+
+
+ Test\XmlFiles\xsd\78985.xsd
+
+
+ Test\XmlFiles\xsd\79650.xsd
+
+
+ Test\XmlFiles\xsd\81360.xsd
+
+
+ Test\XmlFiles\xsd\81360inc1.xsd
+
+
+ Test\XmlFiles\xsd\81360inc2.xsd
+
+
+ Test\XmlFiles\xsd\82010.xml
+
+
+ Test\XmlFiles\xsd\82010.xsd
+
+
+ Test\XmlFiles\xsd\82078.xsd
+
+
+ Test\XmlFiles\xsd\datatypesTest.xsd
+
+
+ Test\XmlFiles\xsd\extension-attr-redefine-1.xsd
+
+
+ Test\XmlFiles\xsd\extension-attr-redefine-2.xsd
+
+
+ Test\XmlFiles\xsd\extension-attr-redefine-3.xsd
+
+
+ Test\XmlFiles\xsd\import-subst-dbr-base.xsd
+
+
+ Test\XmlFiles\xsd\import-subst-dbr-ext.xsd
+
+
+ Test\XmlFiles\xsd\importNamespaceTest.xsd
+
+
+ Test\XmlFiles\xsd\importNamespaceTest2.xsd
+
+
+ Test\XmlFiles\xsd\importedNamespace.xsd
+
+
+ Test\XmlFiles\xsd\importedNamespace2.xsd
+
+
+ Test\XmlFiles\xsd\inter-inc-1.xsd
+
+
+ Test\XmlFiles\xsd\inter-inc-2.xsd
+
+
+ Test\XmlFiles\xsd\multi-schemaLocation.xml
+
+
+ Test\XmlFiles\xsd\resolveUriSchema.xsd
+
+
+ Test\XmlFiles\xsd\x-net-config-schema.xsd
+
+
+ Test\XmlFiles\xsd\x-net-config-storage-factory-provider-schema.xsd
+
+
+ Test\XmlFiles\xsd\xml.xsd
+
+
+ Test\XmlFiles\xsd\xsdimporttest.xml
+
+
+ Test\XmlFiles\xsl\316238-1.xsl
+
+
+ Test\XmlFiles\xsl\316238-2.xsl
+
+
+ Test\XmlFiles\xsl\325482.xml
+
+
+ Test\XmlFiles\xsl\325482.xsl
+
+
+ Test\XmlFiles\xsl\391424.xml
+
+
+ Test\XmlFiles\xsl\391424.xsl
+
+
+ Test\XmlFiles\xsl\82493.xml
+
+
+ Test\XmlFiles\xsl\82493.xsl
+
+
+ Test\XmlFiles\xsl\91834.xml
+
+
+ Test\XmlFiles\xsl\91834.xsl
+
+
+ Test\XmlFiles\xsl\91834a.xml
+
+
+ Test\XmlFiles\xsl\current-in-select.ref
+
+
+ Test\XmlFiles\xsl\current-in-select.xml
+
+
+ Test\XmlFiles\xsl\current-in-select.xsl
+
+
+ Test\XmlFiles\xsl\empty.xsl
+
+
+ Test\XmlFiles\xsl\stripspace.xml
+
+
+ Test\XmlFiles\xsl\stripspace.xsl
+
+
+ Test\XmlFiles\XsdValidation\1.xsd
+
+
+ Test\XmlFiles\XsdValidation\2.xsd
+
+
+ Test\XmlFiles\XsdValidation\3.xsd
+
+
+ Test\XmlFiles\XsdValidation\4.xsd
+
+
+ Test\XmlFiles\496192.xml
+
+
+ Test\XmlFiles\496192.xsd
+
+
+ Test\XmlFiles\595947.xsd
+
+
+ Test\XmlFiles\676993.xml
+
+
+ Test\XmlFiles\676993.xsd
+
+
+ Test\XmlFiles\76102.xml
+
+
+ Test\XmlFiles\79683.dtd
+
+
+ Test\XmlFiles\literal-data.xml
+
+
+ Test\XmlFiles\nested-dtd-test.dtd
+
+
+ Test\XmlFiles\nested-dtd-test.xml
+
+
+ Test\XmlFiles\nested-included.dtd
+
+
+ Test\XmlFiles\simple.xml
+
+
+ Test\System.Xml\nist_dom\files\noDTDXMLfile.xml
+
+
+ Test\System.Xml\nist_dom\files\otherDoc.xml
+
+
+ Test\System.Xml\nist_dom\files\staff.dtd
+
+
+ Test\System.Xml\nist_dom\files\staff.html
+
+
+ Test\System.Xml\nist_dom\files\staff.xml
+
+
+
diff --git a/tests/bcl-test/System/Info.plist b/tests/bcl-test/System/Info.plist
new file mode 100644
index 000000000000..9d1bc3322d07
--- /dev/null
+++ b/tests/bcl-test/System/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.systemtests
+
+
diff --git a/tests/bcl-test/System/Makefile b/tests/bcl-test/System/Makefile
new file mode 100644
index 000000000000..37858a94f291
--- /dev/null
+++ b/tests/bcl-test/System/Makefile
@@ -0,0 +1,4 @@
+
+LIB=System
+
+include ../Make.frag
diff --git a/tests/bcl-test/System/System.csproj.template b/tests/bcl-test/System/System.csproj.template
new file mode 100644
index 000000000000..4e8038e4d993
--- /dev/null
+++ b/tests/bcl-test/System/System.csproj.template
@@ -0,0 +1,124 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {EEE20F63-4282-450A-8584-93F640929D13}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ SystemTests
+ 67,168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+ Assert.cs
+
+
+
+#FILES#
+
+
+
diff --git a/tests/bcl-test/mscorlib/Info.plist b/tests/bcl-test/mscorlib/Info.plist
new file mode 100644
index 000000000000..3c8865dcff0b
--- /dev/null
+++ b/tests/bcl-test/mscorlib/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+ UIApplicationExitsOnSuspend
+
+ CFBundleIdentifier
+ com.xamarin.mscorlibtests
+
+
diff --git a/tests/bcl-test/mscorlib/Makefile b/tests/bcl-test/mscorlib/Makefile
new file mode 100644
index 000000000000..6179234fa745
--- /dev/null
+++ b/tests/bcl-test/mscorlib/Makefile
@@ -0,0 +1,5 @@
+
+LIB=mscorlib
+APP=mscorlib
+
+include ../Make.frag
diff --git a/tests/bcl-test/mscorlib/mscorlib.csproj.template b/tests/bcl-test/mscorlib/mscorlib.csproj.template
new file mode 100644
index 000000000000..fffaa18741a7
--- /dev/null
+++ b/tests/bcl-test/mscorlib/mscorlib.csproj.template
@@ -0,0 +1,138 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 10.0.0
+ 2.0
+ {34CB1751-E445-4E32-BFA7-03E6831C11EE}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ BCL.Tests
+ Resources
+ mscorlibtests
+ 168,169,219,414,612,618,649,672
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ True
+ None
+ False
+ True
+ i386
+
+
+ none
+ True
+ bin\iPhoneSimulator\Release
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ i386
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ iPhone Developer
+ True
+ False
+ True
+ cjk
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Release
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ cjk
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\Ad-Hoc
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ iPhone Distribution
+ True
+ Automatic:AdHoc
+ True
+ ARMv7
+
+
+ none
+ True
+ bin\iPhone\AppStore
+ INSIDE_CORLIB;LIBC;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;MONO_DATACONVERTER_STATIC_METHODS;NET_2_1;MOBILE;MONOTOUCH
+ prompt
+ 4
+ False
+ Automatic:AppStore
+ iPhone Distribution
+ True
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+ AppDelegate.cs
+
+
+
+#FILES#
+
+
+
+
+ Resources\Resources.es-ES.resx
+ Resources.es-ES.resources
+
+
+ Resources\Resources.nn-NO.resx
+ Resources.nn-NO.resources
+
+
+ Resources\Resources.resx
+ Resources.resources
+
+
+
diff --git a/tests/bindings/ApiBaseTest.cs b/tests/bindings/ApiBaseTest.cs
new file mode 100644
index 000000000000..4412763e8c07
--- /dev/null
+++ b/tests/bindings/ApiBaseTest.cs
@@ -0,0 +1,270 @@
+//
+// Base test fixture for introspection tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2015 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using NUnit.Framework;
+using Xamarin.Utils;
+using System.Linq;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#if MONOTOUCH
+using UIKit;
+#endif
+#else
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#endif
+#endif
+
+namespace TouchUnit.Bindings {
+ public abstract class ApiBaseTest {
+ [DllImport ("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
+ protected static extern bool bool_objc_msgSend_IntPtr (IntPtr receiver, IntPtr selector, IntPtr arg1);
+ [DllImport ("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
+ protected static extern IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector);
+
+ private LatchedEnvironmentVariable continueOnFailure = new LatchedEnvironmentVariable ("API_TEST_CONTINUE_ON_FAILURE");
+
+ StringBuilder error_output = new StringBuilder ();
+
+ protected void AddErrorLine (string line)
+ {
+ error_output.AppendLine (line);
+ Console.Error.WriteLine (line);
+ Errors++;
+ }
+
+ protected void AddErrorLine (string format, params object[] parameters)
+ {
+ AddErrorLine (string.Format (format, parameters));
+ }
+
+ ///
+ /// Gets or sets a value indicating whether this test fixture will continue after failures.
+ ///
+ ///
+ /// true if continue on failure; otherwise, false.
+ ///
+ public bool ContinueOnFailure {
+ get { return continueOnFailure.Value; }
+ set { continueOnFailure.Value = value; }
+ }
+
+
+ private LatchedEnvironmentVariable logProgress = new LatchedEnvironmentVariable ("API_TEST_LOG_PROGRESS");
+
+ ///
+ /// Gets or sets a value indicating whether this test fixture will log it's progress.
+ ///
+ ///
+ /// true if log progress; otherwise, false.
+ ///
+ public bool LogProgress {
+ get { return logProgress.Value; }
+ set { logProgress.Value = value; }
+ }
+
+ protected TextWriter Writer {
+#if MONOMAC
+ get { return Console.Out; }
+#elif __WATCHOS__
+ get { return Console.Out; }
+#else
+ get { return DontLink.AppDelegate.Runner.Writer; }
+#endif
+ }
+
+ protected int Errors;
+ protected void ReportError (string s, params object [] parameters)
+ {
+ if (!ContinueOnFailure)
+ Assert.Fail (s, parameters);
+ else {
+ Writer.Write ("[FAIL] ");
+ Writer.WriteLine (s, parameters);
+ Errors++;
+ }
+ }
+
+ protected void AssertIfErrors (string s, params object[] parameters)
+ {
+ if (Errors == 0)
+ return;
+
+ var msg = string.Format (s, parameters);
+ if (error_output.Length > 0) {
+ msg += "\n" + error_output.ToString () + "\n";
+ error_output.Clear ();
+ }
+ Assert.Fail (msg);
+ }
+
+ static protected Type NSObjectType = typeof (NSObject);
+
+ protected virtual bool Skip (Attribute attribute)
+ {
+ return false;
+ }
+
+ protected virtual bool SkipDueToAttribute (MemberInfo member)
+ {
+ if (member == null)
+ return false;
+
+ return !member.IsAvailableOnHostPlatform () ||
+ SkipDueToAttribute (member.DeclaringType) ||
+ SkipDueToAttributeInProperty (member);
+ }
+
+ // We need to check Availability info on PropertyInfo attributes too
+ // due to sometimes the Availability info only exist on the property
+ // and not on the property Getter or Setter, this complements the fix for bug:
+ // https://bugzilla.xamarin.com/show_bug.cgi?id=35176
+ protected bool SkipDueToAttributeInProperty (MemberInfo member)
+ {
+ if (member == null)
+ return false;
+
+ var m = member as MethodInfo;
+
+ if (m == null || // Skip anything that is not a method
+ !m.Attributes.HasFlag (MethodAttributes.SpecialName) ||
+ !m.Name.Contains ("get_")) // We want getters with SpecialName Attribute
+ return false;
+
+ // FIXME: In the future we could cache this to reduce memory requirements
+ var property = m.DeclaringType
+ .GetProperties ()
+ .SingleOrDefault (p => p.GetGetMethod () == m);
+ return property != null && SkipDueToAttribute (property);
+ }
+
+ ///
+ /// Gets the assembly on which the test fixture will reflect the NSObject-derived types.
+ /// The default implementation returns the assembly where NSObject is defined, e.g.
+ /// monotouch.dll or xammac.dll.
+ /// You need to override this method to return the binding assembly you wish to test.
+ ///
+ ///
+ /// The assembly on which the fixture will execute it's tests.
+ ///
+ protected virtual Assembly Assembly {
+ get { return NSObjectType.Assembly; }
+ }
+
+ const string libprefix = "/System/Library/Frameworks";
+ static readonly string simprefix = Environment.GetEnvironmentVariable ("IPHONE_SIMULATOR_ROOT");
+
+ protected virtual string FindLibrary (string libname, bool requiresFullPath = false)
+ {
+ string prefix;
+ if (!String.IsNullOrEmpty (simprefix) && libname.StartsWith (libprefix, StringComparison.Ordinal)) {
+ libname = simprefix + libname;
+ prefix = String.Empty;
+ } else {
+ prefix = libprefix; // re-root libname
+ }
+
+ switch (libname) {
+#if !MONOMAC
+ case "AudioUnit":
+ libname = "AudioToolbox";
+ break;
+#endif
+ case "CoreAnimation":
+ // generated code uses QuartzCore correctly - even if the [Field] property is wrong
+ libname = "QuartzCore";
+ break;
+ case "CoreMidi":
+ // generated code uses CoreMIDI correctly
+ libname = "CoreMIDI";
+ break;
+ default:
+ if (requiresFullPath && (Path.GetDirectoryName (libname).Length == 0))
+ ReportError ("[FAIL] Library '{0}' is specified without a path", libname);
+ break;
+ }
+
+ return Path.Combine (prefix, libname + ".framework", libname);
+ }
+
+ protected bool IsOSX11OrIOS9 {
+ get {
+#if MONOMAC
+ return MonoMacFixtures.Mac.IsElCapitanOrHigher;
+#elif __WATCHOS__
+ return false;
+#else
+ return UIDevice.CurrentDevice.CheckSystemVersion (9, 0);
+#endif
+ }
+ }
+
+ protected bool CheckiOSSystemVersion (int major, int minor)
+ {
+#if __IOS__
+ return UIDevice.CurrentDevice.CheckSystemVersion (major, minor);
+#else
+ throw new InvalidOperationException ("Can only check iOS system version on iOS.");
+#endif
+ }
+
+ // This only works for API introduced in the same numeric version in both iOS and tvOS.
+ protected bool CheckiOSOrTVOSSystemVersion (int major, int minor)
+ {
+#if __IOS__ || __TVOS__
+ return UIDevice.CurrentDevice.CheckSystemVersion (major, minor);
+#else
+ throw new InvalidOperationException ("Can only check iOS or tvOS system version on iOS or tvOS.");
+#endif
+ }
+
+ protected bool CheckWatchOSSystemVersion (int major, int minor)
+ {
+#if __WATCHOS__
+ throw new NotImplementedException ();
+// return UIDevice.CurrentDevice.CheckSystemVersion (major, minor);
+#else
+ throw new InvalidOperationException ("Can only check watchOS system version on watchOS.");
+#endif
+ }
+
+ protected bool CheckTVOSSystemVersion (int major, int minor)
+ {
+#if __TVOS__
+ return UIDevice.CurrentDevice.CheckSystemVersion (major, minor);
+#else
+ throw new InvalidOperationException ("Can only check tvOS system version on tvOS.");
+#endif
+ }
+ }
+}
diff --git a/tests/bindings/ApiCoreImageFiltersTest.cs b/tests/bindings/ApiCoreImageFiltersTest.cs
new file mode 100644
index 000000000000..a3153aa6f63d
--- /dev/null
+++ b/tests/bindings/ApiCoreImageFiltersTest.cs
@@ -0,0 +1,211 @@
+//
+// Test the generated API for all CoreImage filters
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013, 2015 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#if !__WATCHOS__
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using CoreImage;
+using Foundation;
+using ObjCRuntime;
+#if !MONOMAC
+using UIKit;
+#endif
+#elif MONOMAC
+using MonoMac.CoreImage;
+using MonoMac.Foundation;
+#else
+using MonoTouch.CoreImage;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#endif
+
+namespace TouchUnit.Bindings {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public abstract class ApiCoreImageFiltersTest : ApiBaseTest {
+
+ static Type CIFilterType = typeof (CIFilter);
+
+ protected virtual bool Skip (Type type)
+ {
+ return Skip (type.Name) || SkipDueToAttribute (type);
+ }
+
+ protected virtual bool Skip (string nativeName)
+ {
+ switch (nativeName) {
+ // Both reported in radar #21548819
+ // NSUnknownKeyException [ valueForUndefinedKey:]: this class is not key value coding-compliant for the key inputPoint2.
+ case "CIDepthOfField":
+ // NSUnknownKeyException [ valueForUndefinedKey:]: this class is not key value coding-compliant for the key inputCropAmount.
+ case "CISunbeamsGenerator":
+ return true;
+ // FIXME: Remove if fixed. Doesn't appear to exist in El Capitan. Reported in radar #22099780
+// case "CIMaskedVariableBlur":
+// cd .. return true;
+ default:
+ return false;
+ }
+ }
+
+ [Test]
+ // this test checks that all native filters have a managed peer, i.e. against missing filters
+ public void CheckNativeFilters ()
+ {
+ List filters = new List ();
+ int n = 0;
+ string qname = CIFilterType.AssemblyQualifiedName;
+ // that will give us only the list of filters supported by the executing version of iOS
+ foreach (var filter_name in CIFilter.FilterNamesInCategories (null)) {
+ if (Skip (filter_name))
+ continue;
+ string type_name = qname.Replace ("CIFilter", filter_name);
+ if (Type.GetType (type_name, false, true) == null) {
+ filters.Add (filter_name);
+ // uncomment to generate bindings for any new native filter
+// GenerateBinding (CIFilter.FromName (filter_name), Console.Out);
+ }
+ n++;
+ }
+ Assert.That (filters.Count, Is.EqualTo (0), "{0} native filters missing: {1}", filters.Count, String.Join (", ", filters));
+ }
+
+ [Test]
+ // this test checks that all managed filters have a native peer, i.e. against extra filters
+ public void CheckManagedFilters ()
+ {
+ List filters = new List (CIFilter.FilterNamesInCategories (null));
+ var nspace = CIFilterType.Namespace;
+ var types = CIFilterType.Assembly.GetTypes ();
+ foreach (Type t in types) {
+ if (t.Namespace != nspace)
+ continue;
+
+ if (t.IsAbstract || !CIFilterType.IsAssignableFrom (t))
+ continue;
+
+ // we need to skip the filters that are not supported by the executing version of iOS
+ if (Skip (t))
+ continue;
+
+ var ctor = t.GetConstructor (Type.EmptyTypes);
+ if ((ctor == null) || ctor.IsAbstract)
+ continue;
+
+ NSObject obj = ctor.Invoke (null) as NSObject;
+ Assert.That (obj.Handle, Is.Not.EqualTo (IntPtr.Zero), t.Name + ".Handle");
+#if false
+ // check base type - we might have our own base type or different names, so it's debug only (not failure)
+ var super = new Class (obj.Class.SuperClass).Name;
+ var bt = t.BaseType.Name;
+ if ((super != bt) && (bt == "CIFilter")) // check if we should (like Apple) use a non-default base type for filters
+ Console.WriteLine ("[WARN] {0}.SuperClass == {1} (native) and {2} managed", t.Name, super, bt);
+#endif
+ int result = filters.RemoveAll (s => StringComparer.OrdinalIgnoreCase.Compare (t.Name, s) == 0);
+ Assert.That (result, Is.GreaterThan (0), t.Name);
+ }
+ // in case it's a buggy filter we need to try to remove it from the list too
+ for (int i = filters.Count - 1; i >= 0; i--) {
+ if (Skip (filters [i]))
+ filters.RemoveAt (i);
+ }
+ Assert.That (filters.Count, Is.EqualTo (0), "Managed filters not found for {0}", String.Join (", ", filters));
+ }
+
+ static void GenerateBinding (NSObject filter, TextWriter writer)
+ {
+ NSObject value;
+ var attributes = (filter as CIFilter).Attributes;
+
+ writer.WriteLine ("[CoreImageFilter]");
+
+ if (!attributes.TryGetValue ((NSString)"CIAttributeFilterAvailable_iOS", out value)) {
+ writer.WriteLine ("[NoiOS]");
+ } else {
+ var v = value.ToString ();
+ // in the (quite common) case we get "5" for iOS 5.0
+ if (v.IndexOf ('.') == -1)
+ v += ".0";
+ var ios = Version.Parse (v);
+ // we only document availability for iOS 6+
+ if (ios.Major > 5)
+ writer.WriteLine ("[iOS ({0},{1})]", ios.Major, ios.Minor);
+ }
+
+ if (!attributes.TryGetValue ((NSString)"CIAttributeFilterAvailable_Mac", out value)) {
+ writer.WriteLine ("[NoMac]");
+ } else {
+ try {
+ var mac = Version.Parse (value.ToString ());
+ // we only document availability for 10.7+
+ if (mac.Minor > 6)
+ writer.WriteLine ("[Mac ({0},{1})]", mac.Major, mac.Minor);
+ }
+ catch (FormatException) {
+ // 10.? is not a valid version - we'll assume it was added a long time ago (in a galaxy far away)
+ writer.WriteLine ("// incorrect version string for OSX: '{0}' Double-check documentation", value);
+ }
+ }
+ writer.WriteLine ("[BaseType (typeof (CIFilter))]");
+ var fname = attributes [(NSString)"CIAttributeFilterName"].ToString ();
+ writer.WriteLine ("interface {0} {{", fname);
+ foreach (var k in attributes.Keys) {
+ var key = k.ToString ();
+ if (key.StartsWith ("CIAttribute", StringComparison.Ordinal))
+ continue;
+ // CIFilter defines it for all filters
+ if (key == "inputImage")
+ continue;
+
+ writer.WriteLine ();
+ var dict = attributes [k] as NSDictionary;
+ var type = dict [(NSString) "CIAttributeClass"];
+ writer.WriteLine ("\t[CoreImageProperty (\"{0}\")]", key);
+
+ // by default we drop the "input" prefix, but keep the "output" prefix to avoid confusion
+ if (key.StartsWith ("input", StringComparison.Ordinal))
+ key = Char.ToUpperInvariant (key [5]) + key.Substring (6);
+
+ var ptype = type.ToString ();
+ // Too many things ends up in NSNumber but we do a better job in our bindings
+ if (ptype == "NSNumber") {
+ ptype = "float";
+ writer.WriteLine ("\t// TODO: this was an NSNumber transformed to float, but maybe an int or bool is more appropriate");
+ }
+ writer.WriteLine ("\t{0} {1} {{ get; set; }}", ptype, key);
+ }
+ writer.WriteLine ("}");
+ writer.WriteLine ();
+ }
+ }
+}
+
+#endif // !__WATCHOS__
diff --git a/tests/bindings/ApiCtorInitTest.cs b/tests/bindings/ApiCtorInitTest.cs
new file mode 100644
index 000000000000..2eff40f7f751
--- /dev/null
+++ b/tests/bindings/ApiCtorInitTest.cs
@@ -0,0 +1,306 @@
+//
+// Test the generated API `init` selectors are usable by the binding consumers
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2015 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Reflection;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+
+ public abstract class ApiCtorInitTest : ApiBaseTest {
+
+ string instance_type_name;
+
+ ///
+ /// Gets or sets a value indicating whether this test fixture will log untested types.
+ ///
+ /// true if log untested types; otherwise, false.
+ public bool LogUntestedTypes { get; set; }
+
+ ///
+ /// Override this method if you want the test to skip some specific types.
+ /// By default types decorated with [Model] will be skipped.
+ ///
+ /// The Type to be tested
+ protected virtual bool Skip (Type type)
+ {
+ if (type.ContainsGenericParameters)
+ return true;
+
+ // skip delegate (and other protocol references)
+ foreach (object ca in type.GetCustomAttributes (false)) {
+ if (ca is ProtocolAttribute)
+ return true;
+ if (ca is ModelAttribute)
+ return true;
+ }
+ switch (type.Name) {
+#if !XAMCORE_2_0
+ case "AVAssetResourceLoader": // We have DisableDefaultCtor in XAMCORE_2_0 but can't change in compat because of backwards compat
+ case "AVAssetResourceLoadingRequest":
+ case "AVAssetResourceLoadingContentInformationRequest":
+#endif
+ // on iOS 8.2 (beta 1) we get: NSInvalidArgumentException Caller did not provide an activityType, and this process does not have a NSUserActivityTypes in its Info.plist.
+ // even if we specify an NSUserActivityTypes in the Info.plist - might be a bug or there's a new (undocumented) requirement
+ case "NSUserActivity":
+ return true;
+ }
+ return SkipDueToAttribute (type);
+ }
+
+ ///
+ /// Checks that the Handle property of the specified NSObject instance is not null (not IntPtr.Zero).
+ ///
+ /// NSObject instance to validate
+ protected virtual void CheckHandle (NSObject obj)
+ {
+ if (obj.Handle == IntPtr.Zero)
+ ReportError ("{0} : Handle", instance_type_name);
+ }
+
+ ///
+ /// Checks that ToString does not return null (not helpful for debugging) and that it does not crash.
+ ///
+ /// NSObject instance to validate
+ protected virtual void CheckToString (NSObject obj)
+ {
+ if (obj.ToString () == null)
+ ReportError ("{0} : ToString", instance_type_name);
+ }
+
+ bool GetIsDirectBinding (NSObject obj)
+ {
+#if XAMCORE_2_0
+ int flags = (byte) typeof (NSObject).GetField ("flags", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic).GetValue (obj);
+ return (flags & 4) == 4;
+#else
+ return (bool) typeof (NSObject).GetField ("IsDirectBinding", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic).GetValue (obj);
+#endif
+ }
+
+ ///
+ /// Checks that the IsDirectBinding property is identical to the IsWrapper property of the Register attribute.
+ ///
+ /// Object.
+ protected virtual void CheckIsDirectBinding (NSObject obj)
+ {
+ var attrib = obj.GetType ().GetCustomAttribute (false);
+ // only check types that we register - that way we avoid the 118 MonoTouch.CoreImagge.CI* "special" types
+ if (attrib == null)
+ return;
+ var is_wrapper = attrib != null && attrib.IsWrapper;
+ var is_direct_binding = GetIsDirectBinding (obj);
+ if (is_direct_binding != is_wrapper)
+ ReportError ("{0} : IsDirectBinding (expected {1}, got {2})", instance_type_name, is_wrapper, is_direct_binding);
+ }
+
+ ///
+ /// Skip, or not, the specified pproperty from being verified.
+ ///
+ /// PropertyInfo candidate
+ protected virtual bool Skip (PropertyInfo pi)
+ {
+ // manually bound API can have the attributes only on the property (and not on the getter/setter)
+ return SkipDueToAttribute (pi);
+ }
+
+ ///
+ /// Dispose the specified NSObject instance. In some cases objects cannot be disposed safely.
+ /// Override this method to keep them alive while the remaining tests execute.
+ ///
+ /// NSObject instance to dispose
+ /// Type of the object, to be used if special logic is required.
+ protected virtual void Dispose (NSObject obj, Type type)
+ {
+ obj.Dispose ();
+ }
+
+ protected virtual void CheckNSObjectProtocol (NSObject obj)
+ {
+ // not documented to allow null, but commonly used this way. OTOH it's not clear what code answer this
+ // (it might be different implementations) but we can make sure that Apple allows null with this test
+ // ref: https://bugzilla.xamarin.com/show_bug.cgi?id=35924
+ var kind_of_null = obj.IsKindOfClass (null);
+ if (kind_of_null)
+ ReportError ("{0} : IsKindOfClass(null) failed", instance_type_name);
+ var is_member_of_null = obj.IsMemberOfClass (null);
+ if (is_member_of_null)
+ ReportError ("{0} : IsMemberOfClass(null) failed", instance_type_name);
+ var respond_to_null = obj.RespondsToSelector (null);
+ if (respond_to_null)
+ ReportError ("{0} : RespondToSelector(null) failed", instance_type_name);
+ var conforms_to_null = obj.ConformsToProtocol (IntPtr.Zero);
+ if (conforms_to_null)
+ ReportError ("{0} : ConformsToProtocol(null) failed", instance_type_name);
+ }
+
+ // if a .ctor is obsolete then it's because it was not usable (nor testable)
+ protected override bool SkipDueToAttribute (MemberInfo member)
+ {
+ if (member == null)
+ return false;
+ var ca = member.GetCustomAttribute ();
+ return ca != null || base.SkipDueToAttribute (member);
+ }
+
+ [Test]
+ public void DefaultCtorAllowed ()
+ {
+ Errors = 0;
+ int n = 0;
+
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (t.IsAbstract || !NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ if (Skip (t))
+ continue;
+
+ var ctor = t.GetConstructor (Type.EmptyTypes);
+ if (SkipDueToAttribute (ctor))
+ continue;
+
+ if ((ctor == null) || ctor.IsAbstract) {
+ if (LogUntestedTypes)
+ Console.WriteLine ("[WARNING] {0} was skipped because it had no default constructor", t);
+ continue;
+ }
+
+ instance_type_name = t.FullName;
+ if (LogProgress)
+ Console.WriteLine ("{0}. {1}", n, instance_type_name);
+
+ NSObject obj = null;
+ try {
+ obj = ctor.Invoke (null) as NSObject;
+ CheckHandle (obj);
+ CheckToString (obj);
+ CheckIsDirectBinding (obj);
+ CheckNSObjectProtocol (obj);
+ Dispose (obj, t);
+ }
+ catch (Exception e) {
+ // Objective-C exception thrown
+ if (!ContinueOnFailure)
+ throw;
+
+ TargetInvocationException tie = (e as TargetInvocationException);
+ if (tie != null)
+ e = tie.InnerException;
+ ReportError ("Default constructor not allowed for {0} : {1}", instance_type_name, e.Message);
+ }
+ n++;
+ }
+ Assert.AreEqual (0, Errors, "{0} potential errors found in {1} default ctor validated", Errors, n);
+ }
+
+ // .NET constructors are not virtual, so we need to re-expose the base class .ctor when a subclass is created.
+ // That's very important for designated initializer since we can end up with no correct/safe way to create
+ // subclasses of an existing type
+ [Test]
+ public void DesignatedInitializer ()
+ {
+ Errors = 0;
+ int n = 0;
+
+ foreach (Type t in Assembly.GetTypes ()) {
+ // we only care for NSObject subclasses that we expose publicly
+ if (!t.IsPublic || !NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ int designated = 0;
+ foreach (var ctor in t.GetConstructors ()) {
+ if (ctor.GetCustomAttribute () == null)
+ continue;
+ designated++;
+ }
+ // that does not mean that inlining is not required, i.e. it might be useful, even needed
+ // but it's not a showstopper for subclassing so we'll start with those cases
+ if (designated > 1)
+ continue;
+
+ var base_class = t.BaseType;
+ // NSObject ctor requirements are handled by the generator
+ if (base_class == NSObjectType)
+ continue;
+ foreach (var ctor in base_class.GetConstructors ()) {
+ // if the base ctor is a designated (not a convenience) initializer then we should re-expose it
+ if (ctor.GetCustomAttribute () == null)
+ continue;
+
+ // check if this ctor (from base type) is exposed in the current (subclass) type
+ if (!Match (ctor, t))
+ ReportError ("{0} should re-expose {1}::{2}", t, base_class.Name, ctor.ToString ().Replace ("Void ", String.Empty));
+ n++;
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} potential errors found in {1} designated initializer validated", Errors, n);
+ }
+
+ protected virtual bool Match (ConstructorInfo ctor, Type type)
+ {
+ switch (type.Name) {
+ case "MKTileOverlayRenderer":
+ // NSInvalidArgumentEception Expected a MKTileOverlay
+ // looks like Apple has not yet added a DI for this type, but it should be `initWithTileOverlay:`
+ if (ctor.ToString () == "Void .ctor(IMKOverlay)")
+ return true;
+ break;
+ case "MPSImageHistogram":
+ // Could not initialize an instance of the type 'MetalPerformanceShaders.MPSImageHistogram': the native 'initWithDevice:' method returned nil.
+ // make sense: there's a `initWithDevice:histogramInfo:` DI
+ if (ctor.ToString () == "Void .ctor(IMTLDevice)")
+ return true;
+ break;
+ case "NSDataDetector":
+ // -[NSDataDetector initWithPattern:options:error:]: Not valid for NSDataDetector
+ if (ctor.ToString () == "Void .ctor(NSString, NSRegularExpressionOptions, NSError&)")
+ return true;
+ break;
+#if __TVOS__
+ case "UISearchBar":
+ // - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER __TVOS_PROHIBITED;
+ return true;
+#endif
+ }
+
+ var expected = ctor.ToString ();
+ // NonPublic to get `protected` which can be autogenerated for abstract types (subclassing a non-abstract type)
+ foreach (var candidate in type.GetConstructors (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
+ if (candidate.ToString () == expected)
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/tests/bindings/ApiFieldTest.cs b/tests/bindings/ApiFieldTest.cs
new file mode 100644
index 000000000000..f60721693605
--- /dev/null
+++ b/tests/bindings/ApiFieldTest.cs
@@ -0,0 +1,187 @@
+//
+// Test the generated API fields (e.g. against typos or unexisting values for the platform)
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2014 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Reflection;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+
+ [Preserve (AllMembers = true)]
+ public abstract class ApiFieldTest : ApiBaseTest {
+#if XAMCORE_2_0
+ const string NSStringType = "Foundation.NSString";
+#elif MONOMAC
+ const string NSStringType = "MonoMac.Foundation.NSString";
+#else
+ const string NSStringType = "MonoTouch.Foundation.NSString";
+#endif
+
+ ///
+ /// Override if you want to skip testing the specified type.
+ ///
+ /// Type to be tested
+ protected virtual bool Skip (Type type)
+ {
+ return false;
+ }
+
+ ///
+ /// Override if you want to skip testing the specified property.
+ ///
+ /// Property to be tested
+ protected virtual bool Skip (PropertyInfo property)
+ {
+ return SkipDueToAttribute (property);
+ }
+
+ ///
+ /// Override if you want to skip testing the specified constant.
+ ///
+ /// Constant name to ignore.
+ protected virtual bool Skip (string constantName)
+ {
+ return false;
+ }
+
+ // check generated code, which are static properties, e.g.
+ // [Field ("kCGImagePropertyIPTCObjectTypeReference")]
+ // NSString IPTCObjectTypeReference { get; }
+ bool CheckAgainstNull (PropertyInfo p, out string name)
+ {
+ name = String.Empty;
+ var g = p.GetGetMethod (true);
+ if (!g.IsStatic)
+ return true;
+
+ if (Skip (p))
+ return true;
+
+ try {
+ // if it return nulls then it could be a typo...
+ // or something not available in the executing version of iOS
+ bool result = g.Invoke (null, null) != null;
+ if (!result)
+ name = p.DeclaringType.FullName + "." + p.Name;
+ return result;
+ }
+ catch (Exception e) {
+ Console.WriteLine ("[FAIL] Exception on '{0}' : {1}", p, e);
+ name = p.DeclaringType.FullName + "." + p.Name;
+ return false;
+ }
+ }
+
+ [Test]
+ public void NonNullNSStringFields ()
+ {
+ var failed_fields = new List ();
+
+ Errors = 0;
+ int c = 0, n = 0;
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (Skip (t) || SkipDueToAttribute (t))
+ continue;
+
+ if (LogProgress)
+ Console.WriteLine ("{0}. {1}", c++, t.FullName);
+
+ foreach (var p in t.GetProperties (BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) {
+ // looking for properties with getters only
+ if (p.CanWrite || !p.CanRead)
+ continue;
+
+ if (p.PropertyType.FullName != NSStringType)
+ continue;
+
+ if (SkipDueToAttribute (p))
+ continue;
+
+ string name;
+ bool result = CheckAgainstNull (p, out name);
+ if (!result) {
+ ReportError (name);
+ failed_fields.Add (name);
+ }
+ n++;
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} fields validated: {2}", Errors, n, string.Join (", ", failed_fields));
+ }
+
+ [Test]
+ public void FieldExists ()
+ {
+ var failed_fields = new List ();
+
+ Errors = 0;
+ int c = 0, n = 0;
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (Skip (t) || SkipDueToAttribute (t))
+ continue;
+
+ if (LogProgress)
+ Console.WriteLine ("{0}. {1}", c++, t.FullName);
+
+ foreach (var p in t.GetProperties (BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) {
+ // looking for properties with getters only
+ if (p.CanWrite || !p.CanRead)
+ continue;
+
+ if (SkipDueToAttribute (p))
+ continue;
+
+ var f = p.GetCustomAttribute ();
+ if (f == null)
+ continue;
+
+ string name = f.SymbolName;
+ if (Skip (name))
+ continue;
+
+ string path = FindLibrary (f.LibraryName);
+ IntPtr lib = Dlfcn.dlopen (path, 0);
+ if (Dlfcn.GetIndirect (lib, name) == IntPtr.Zero) {
+ ReportError ("Could not find the field '{0}' in {1}", name, path);
+ failed_fields.Add (name);
+ }
+ Dlfcn.dlclose (lib);
+ n++;
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} fields validated: {2}", Errors, n, string.Join (", ", failed_fields));
+ }
+ }
+}
diff --git a/tests/bindings/ApiPInvokeTest.cs b/tests/bindings/ApiPInvokeTest.cs
new file mode 100644
index 000000000000..f3869533b02c
--- /dev/null
+++ b/tests/bindings/ApiPInvokeTest.cs
@@ -0,0 +1,259 @@
+//
+// ApiPInvokeTest.cs: enforce P/Invoke signatures
+//
+// Authors:
+// Aaron Bockover
+// Sebastien Pouliot
+//
+// Copyright 2013-2014 Xamarin, Inc.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using ObjCRuntime;
+using Foundation;
+#elif MONOMAC
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+#endif
+
+namespace TouchUnit.Bindings
+{
+ [Preserve (AllMembers = true)]
+ public abstract class ApiPInvokeTest : ApiBaseTest {
+ IEnumerable pinvokeQuery;
+
+ public ApiPInvokeTest ()
+ {
+ ContinueOnFailure = true;
+ LogProgress = false;
+
+ pinvokeQuery = from type in Assembly.GetTypes ()
+ where !Skip (type)
+ from mi in type.GetMethods (
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.Static)
+ let attr = mi.GetCustomAttribute ()
+ where attr != null && !Skip (mi)
+ select mi;
+ }
+
+ protected virtual bool Skip (Type type)
+ {
+ return SkipDueToAttribute (type);
+ }
+
+ protected virtual bool Skip (MethodInfo methodInfo)
+ {
+ return SkipDueToAttribute (methodInfo);
+ }
+
+ [Test]
+ public void Signatures ()
+ {
+ int totalPInvokes = 0;
+ int totalErrors = 0;
+
+ foreach (MethodInfo mi in pinvokeQuery) {
+ totalPInvokes++;
+ if (!CheckSignature (mi)) {
+ totalErrors++;
+
+ if (!ContinueOnFailure)
+ break;
+ }
+ }
+
+ AssertIfErrors (
+ "{0} errors found in {1} P/Invoke signatures validated",
+ totalErrors, totalPInvokes);
+ }
+
+ protected virtual bool CheckSignature (MethodInfo mi)
+ {
+ var success = true;
+
+ if (!CheckReturnParameter (mi, mi.ReturnParameter))
+ success = false;
+
+ foreach (var pi in mi.GetParameters ()) {
+ if (!CheckParameter (mi, pi))
+ success = false;
+ }
+
+ return success;
+ }
+
+ protected virtual bool CheckReturnParameter (MethodInfo mi, ParameterInfo pi)
+ {
+ return CheckForEnumParameter (mi, pi);
+ }
+
+ protected virtual bool CheckParameter (MethodInfo mi, ParameterInfo pi)
+ {
+ return CheckForEnumParameter (mi, pi);
+ }
+
+ protected virtual bool CheckForEnumParameter (MethodInfo mi, ParameterInfo pi)
+ {
+ if (pi.ParameterType.IsEnum && pi.ParameterType.GetCustomAttribute () != null) {
+ AddErrorLine ("{0}.{1} has a [Native] enum parameter in its signature: {2} {3}",
+ mi.DeclaringType.FullName, mi.Name, pi.ParameterType, pi.Name);
+ return false;
+ }
+
+ return true;
+ }
+
+ protected virtual bool Skip (string symbolName)
+ {
+ return false;
+ }
+
+ protected virtual bool SkipLibrary (string libraryName)
+ {
+ return false;
+ }
+
+ [Test]
+ public void SymbolExists ()
+ {
+ var failed_api = new List ();
+ Errors = 0;
+ int c = 0, n = 0;
+ foreach (MethodInfo mi in pinvokeQuery) {
+
+ if (LogProgress)
+ Console.WriteLine ("{0}. {1}", c++, mi);
+
+ var dllimport = mi.GetCustomAttribute ();
+
+ string libname = dllimport.Value;
+ if (libname == "__Internal" || SkipLibrary (libname))
+ continue;
+
+ string path = FindLibrary (dllimport.Value, requiresFullPath: true);
+
+ string name = dllimport.EntryPoint ?? mi.Name;
+ if (Skip (name))
+ continue;
+
+ IntPtr lib = Dlfcn.dlopen (path, 0);
+ if (Dlfcn.GetIndirect (lib, name) == IntPtr.Zero) {
+ ReportError ("Could not find the field '{0}' in {1}", name, path);
+ failed_api.Add (name);
+ }
+ Dlfcn.dlclose (lib);
+ n++;
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} functions validated: {2}", Errors, n, string.Join (", ", failed_api));
+ }
+
+ // we just want to confirm the symbol exists so `dlsym` can be disabled
+ protected void Check (Assembly a)
+ {
+ Errors = 0;
+ int n = 0;
+ foreach (var t in a.GetTypes ()) {
+ foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)) {
+ if ((m.Attributes & MethodAttributes.PinvokeImpl) == 0)
+ continue;
+
+ var dllimport = m.GetCustomAttribute ();
+
+ string name = dllimport.EntryPoint ?? m.Name;
+ switch (name) {
+ // known not to be present in ARM64
+ case "objc_msgSend_stret":
+ case "objc_msgSendSuper_stret":
+ // the linker normally removes them (IntPtr.Size optimization)
+ continue;
+ }
+
+ string path = dllimport.Value;
+ switch (path) {
+ case "__Internal":
+ // load from executable
+ path = null;
+ break;
+ case "libc":
+ // we still have some rogue/not-fully-qualified DllImport
+ path = "/usr/lib/libSystem.dylib";
+ break;
+ }
+
+ var lib = Dlfcn.dlopen (path, 0);
+ var h = Dlfcn.dlsym (lib, name);
+ if (h == IntPtr.Zero)
+ ReportError ("Could not find the symbol '{0}' in {1}", name, path);
+ Dlfcn.dlclose (lib);
+ n++;
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} symbol lookups", Errors, n);
+ }
+
+ protected abstract bool SkipAssembly (Assembly a);
+
+ // Note: this looks very similar to the "SymbolExists" test above (and it is)
+ // except that we never skip based on availability attributes or __Internal...
+ // since this is a test to ensure thigns will work at native link time (e.g.
+ // for devices) when dlsym is disabled
+
+ [Test]
+ public void Product ()
+ {
+ var a = typeof (NSObject).Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+
+ // since we already have non-linked version of the most common assemblies available here
+ // we can use them to check for missing symbols (from DllImport)
+ // it's not complete (there's many more SDK assemblies) but we cannot add all of them into a single project anyway
+
+ [Test]
+ public void Corlib ()
+ {
+ var a = typeof (int).Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+
+ [Test]
+ public void System ()
+ {
+ var a = typeof (System.Net.WebClient).Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+
+ [Test]
+ public void SystemCore ()
+ {
+ var a = typeof (Enumerable).Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+
+ [Test]
+ public void SystemXml ()
+ {
+ var a = typeof (System.Xml.XmlDocument).Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+ }
+}
diff --git a/tests/bindings/ApiProtocolTest.cs b/tests/bindings/ApiProtocolTest.cs
new file mode 100644
index 000000000000..3e649a2293cd
--- /dev/null
+++ b/tests/bindings/ApiProtocolTest.cs
@@ -0,0 +1,297 @@
+//
+// Test the generated API for common protocol support
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013, 2015 Xamarin Inc.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+
+ public abstract class ApiProtocolTest : ApiBaseTest {
+
+ static IntPtr conform_to = Selector.GetHandle ("conformsToProtocol:");
+
+ public ApiProtocolTest ()
+ {
+ ContinueOnFailure = true;
+ }
+
+ static bool ConformTo (IntPtr klass, IntPtr protocol)
+ {
+ return bool_objc_msgSend_IntPtr (klass, conform_to, protocol);
+ }
+
+ protected virtual bool Skip (Type type)
+ {
+ switch (type.Name) {
+ // *** NSForwarding: warning: object 0x5cbd078 of class 'JSExport' does not implement methodSignatureForSelector: -- trouble ahead
+ // *** NSForwarding: warning: object 0x5cbd078 of class 'JSExport' does not implement doesNotRecognizeSelector: -- abort
+ case "JSExport":
+ return true;
+ default:
+#if !XAMCORE_2_0
+ // in Classic our internal delegates _inherits_ the type with the [Protocol] attribute
+ // in Unified our internal delegates _implements_ the interface that has the [Protocol] attribute
+ if (type.GetCustomAttribute (true) != null)
+ return true;
+#endif
+ return SkipDueToAttribute (type);
+ }
+ }
+
+ IntPtr GetClass (Type type)
+ {
+ return Class.GetHandle (type);
+ }
+
+ protected virtual bool Skip (Type type, string protocolName)
+ {
+ switch (protocolName) {
+ case "NSCopying":
+ switch (type.Name) {
+ // undocumented conformance (up to 7.0) and conformity varies between iOS versions
+ case "CAEmitterCell":
+ case "GKAchievement":
+ case "GKScore":
+ // new in iOS8 and 10.0
+ case "NSExtensionContext":
+ return true; // skip
+ }
+ break;
+ case "NSCoding":
+ switch (type.Name) {
+ // only documented to support NSCopying - not NSCoding (fails on iOS 7.1 but not 8.0)
+ case "NSUrlSessionTask":
+ case "NSUrlSessionDataTask":
+ case "NSUrlSessionUploadTask":
+ case "NSUrlSessionDownloadTask":
+ //
+ case "NSUrlSessionConfiguration":
+ case "NSMergeConflict":
+ // new in iOS8 and 10.0
+ case "NSExtensionContext":
+ case "NSItemProvider":
+ // undocumented
+ return true;
+ }
+ break;
+ case "NSSecureCoding":
+ switch (type.Name) {
+ case "NSMergeConflict": // undocumented
+ // only documented to support NSCopying (and OSX side only does that)
+ case "NSUrlSessionTask":
+ case "NSUrlSessionDataTask":
+ case "NSUrlSessionUploadTask":
+ case "NSUrlSessionDownloadTask":
+ case "NSUrlSessionConfiguration":
+ // new in iOS8 and 10.0
+ case "NSExtensionContext":
+ case "NSItemProvider":
+ case "NSParagraphStyle": //17770106
+ case "NSMutableParagraphStyle": //17770106
+ return true; // skip
+ // iOS9 / 10.11
+ case "NSPersonNameComponentsFormatter":
+ return true; // skip
+ }
+ break;
+ }
+ return false;
+ }
+
+ void CheckProtocol (string protocolName, Action action)
+ {
+ IntPtr protocol = Runtime.GetProtocol (protocolName);
+ Assert.AreNotEqual (protocol, IntPtr.Zero, protocolName);
+
+ int n = 0;
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (!NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ if (Skip (t) || Skip (t, protocolName))
+ continue;
+
+ if (LogProgress)
+ Console.WriteLine ("{0}. {1} conforms to {2}", ++n, t.FullName, protocolName);
+
+ IntPtr klass = GetClass (t);
+ action (t, klass, ConformTo (klass, protocol));
+ }
+ }
+
+ [Test]
+ public void Coding ()
+ {
+ Errors = 0;
+ CheckProtocol ("NSCoding", delegate (Type type, IntPtr klass, bool result) {
+ if (result) {
+ // `type` conforms to (native) NSCoding so...
+ if (result) {
+ // the type should implements INSCoding
+ if (!typeof (INSCoding).IsAssignableFrom (type)) {
+ ReportError ("{0} conforms to NSCoding but does not implement INSCoding", type.Name);
+ }
+ // FIXME: and implement the .ctor(NSCoder)
+ }
+ }
+ });
+ Assert.AreEqual (Errors, 0, "{0} types conforms to NSCoding but does not implement INSCoding", Errors);
+ }
+
+ // [Test] -> iOS 6.0+ and Mountain Lion (10.8) +
+ public virtual void SecureCoding ()
+ {
+ Errors = 0;
+ CheckProtocol ("NSSecureCoding", delegate (Type type, IntPtr klass, bool result) {
+ if (result) {
+ // the type should implements INSSecureCoding
+ if (!typeof (INSSecureCoding).IsAssignableFrom (type)) {
+ ReportError ("{0} conforms to NSSecureCoding but does not implement INSSecureCoding", type.Name);
+ }
+ }
+ });
+ Assert.AreEqual (Errors, 0, "{0} types conforms to NSSecureCoding but does not implement INSSecureCoding", Errors);
+ }
+
+ bool SupportsSecureCoding (Type type)
+ {
+ Class cls = new Class (type);
+ if (!bool_objc_msgSend_IntPtr (cls.Handle, Selector.GetHandle ("respondsToSelector:"), Selector.GetHandle ("supportsSecureCoding")))
+ return false;
+
+ return NSSecureCoding.SupportsSecureCoding (type);
+ }
+
+
+ // [Test] -> iOS 6.0+ and Mountain Lion (10.8) +
+ public virtual void SupportsSecureCoding ()
+ {
+ Errors = 0;
+ CheckProtocol ("NSSecureCoding", delegate (Type type, IntPtr klass, bool result) {
+ bool supports = SupportsSecureCoding (type);
+ if (result) {
+ // check that +supportsSecureCoding returns YES
+ if (!supports) {
+ ReportError ("{0} conforms to NSSecureCoding but SupportsSecureCoding returned false", type.Name);
+ }
+ } else if (type.IsPublic && supports) {
+ // there are internal types, e.g. DataWrapper : NSData, that subclass NSSecureCoding-types without
+ // [re-]declaring their allegiance - but we can live with those small betrayals
+ Assert.IsFalse (NSSecureCoding.SupportsSecureCoding (type), "{0} !SupportsSecureCoding", type.Name);
+ ReportError ("SupportsSecureCoding returns true but {0} does not conforms to NSSecureCoding", type.Name);
+ }
+ });
+ Assert.AreEqual (Errors, 0, "{0} types conforms to NSCoding but does not implement INSSecureCoding", Errors);
+ }
+
+ [Test]
+ public void Copying ()
+ {
+ Errors = 0;
+ CheckProtocol ("NSCopying", delegate (Type type, IntPtr klass, bool result) {
+ // `type` conforms to (native) NSCopying so...
+ if (result) {
+ // the type should implements INSCopying
+ if (!typeof (INSCopying).IsAssignableFrom (type)) {
+ ReportError ("{0} conforms to NSCopying but does not implement INSCopying", type.Name);
+ }
+ }
+ });
+ Assert.AreEqual (Errors, 0, "{0} types conforms to NSCopying but does not implement INSCopying", Errors);
+ }
+
+ [Test]
+ public void MutableCopying ()
+ {
+ Errors = 0;
+ CheckProtocol ("NSMutableCopying", delegate (Type type, IntPtr klass, bool result) {
+ // `type` conforms to (native) NSMutableCopying so...
+ if (result) {
+ // the type should implements INSMutableCopying
+ if (!typeof (INSMutableCopying).IsAssignableFrom (type)) {
+ ReportError ("{0} conforms to NSMutableCopying but does not implement INSMutableCopying", type.Name);
+ }
+ }
+ });
+ Assert.AreEqual (Errors, 0, "{0} types conforms to NSMutableCopying but does not implement INSMutableCopying", Errors);
+ }
+
+ [Test]
+ public void GeneralCase ()
+ {
+ Errors = 0;
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (!NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ if (Skip (t))
+ continue;
+
+ foreach (var intf in t.GetInterfaces ()) {
+ if (SkipDueToAttribute (intf))
+ continue;
+
+ string protocolName = intf.Name.Substring (1);
+ switch (protocolName) {
+ case "NSCoding":
+ case "NSSecureCoding":
+ case "NSCopying":
+ case "NSMutableCopying":
+ // we have special test cases for them
+ continue;
+ default:
+#if !XAMCORE_2_0
+ // in Classic our internal delegates _inherits_ the type with the [Protocol] attribute
+ // in Unified our internal delegates _implements_ the interface that has the [Protocol] attribute
+ var pt = Type.GetType (intf.Namespace + "." + protocolName + ", " + intf.Assembly.FullName);
+ if (SkipDueToAttribute (pt))
+ continue;
+#endif
+ if (Skip (t, protocolName))
+ continue;
+ break;
+ }
+
+ var a = intf.GetCustomAttribute (true);
+ if (a == null || a.IsInformal)
+ continue;
+
+ IntPtr protocol = Runtime.GetProtocol (protocolName);
+ if (protocol == IntPtr.Zero)
+ continue; // not a protocol
+
+ if (LogProgress)
+ Console.WriteLine ("{0} conforms to {1}", t.FullName, protocolName);
+
+ var klass = new Class (t);
+ if (klass.Handle == IntPtr.Zero) {
+ AddErrorLine ("Could not load {0}", t.FullName);
+ } else if (t.IsPublic && !ConformTo (klass.Handle, protocol)) {
+ // note: some internal types, e.g. like UIAppearance subclasses, return false (and there's not much value in changing this)
+ ReportError ("Type {0} (native: {1}) does not conform {2}", t.FullName, klass.Name, protocolName);
+ }
+ }
+ }
+ AssertIfErrors ("{0} types do not really conform to the protocol interfaces", Errors);
+ }
+ }
+}
diff --git a/tests/bindings/ApiSelectorTest.cs b/tests/bindings/ApiSelectorTest.cs
new file mode 100644
index 000000000000..b0ef3fff96fb
--- /dev/null
+++ b/tests/bindings/ApiSelectorTest.cs
@@ -0,0 +1,406 @@
+//
+// Test the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Reflection;
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+
+ public abstract class ApiSelectorTest : ApiBaseTest {
+
+ // not everything should be even tried
+
+ protected virtual bool Skip (Type type)
+ {
+ if (type.ContainsGenericParameters)
+ return true;
+
+ // skip delegate (and other protocol references)
+ foreach (object ca in type.GetCustomAttributes (false)) {
+ if (ca is ProtocolAttribute)
+ return true;
+ if (ca is ModelAttribute)
+ return true;
+ }
+ return SkipDueToAttribute (type);
+ }
+
+ protected virtual bool Skip (Type type, string selectorName)
+ {
+#if !XAMCORE_2_0
+ // old binding mistake
+ if (selectorName == "subscribedCentrals")
+ return true;
+#else
+ // The MapKit types/selectors are optional protocol members pulled in from MKAnnotation/MKOverlay.
+ // These concrete (wrapper) subclasses do not implement all of those optional members, but we
+ // still need to provide a binding for them, so that user subclasses can implement those members.
+ switch (type.Name) {
+ case "MKCircle":
+ case "MKPolygon":
+ case "MKPolyline":
+ switch (selectorName) {
+ case "canReplaceMapContent":
+ return true;
+ }
+ break;
+ case "MKShape":
+ switch (selectorName) {
+ case "setCoordinate:":
+ return true;
+ }
+ break;
+ case "MKPlacemark":
+ switch (selectorName) {
+ case "setCoordinate:":
+ case "subtitle":
+ return true;
+ }
+ break;
+ case "MKTileOverlay":
+ switch (selectorName) {
+ case "intersectsMapRect:":
+ return true;
+ }
+ break;
+ // AVAudioChannelLayout and AVAudioFormat started conforming to NSSecureCoding in OSX 10.11 and iOS 9
+ case "AVAudioChannelLayout":
+ case "AVAudioFormat":
+ switch (selectorName) {
+ case "encodeWithCoder:":
+ return true;
+ }
+ break;
+ // SKTransition started conforming to NSCopying in OSX 10.11 and iOS 9
+ case "SKTransition":
+ switch (selectorName) {
+ case "copyWithZone:":
+ return true;
+ }
+ break;
+ }
+#endif
+ // This ctors needs to be manually bound
+ switch (type.Name) {
+ case "GKPath":
+ switch (selectorName) {
+ case "initWithPoints:count:radius:cyclical:":
+ return true;
+ }
+ break;
+ case "GKPolygonObstacle":
+ switch (selectorName) {
+ case "initWithPoints:count:":
+ return true;
+ }
+ break;
+ case "NSImage":
+ switch (selectorName) {
+ case "initByReferencingFile:":
+ return true;
+ }
+ break;
+ case "SKVideoNode":
+ switch (selectorName) {
+ case "initWithFileNamed:":
+ case "initWithURL:":
+ case "initWithVideoFileNamed:":
+ case "initWithVideoURL:":
+ case "videoNodeWithFileNamed:":
+ case "videoNodeWithURL:":
+ return true;
+ }
+ break;
+ }
+
+ // old binding mistake
+ return (selectorName == "initWithCoder:");
+ }
+
+ protected virtual bool CheckResponse (bool value, Type actualType, MethodBase method, ref string name)
+ {
+ if (value)
+ return true;
+
+ var mname = method.Name;
+ // properties getter and setter will be methods in the _Extensions type
+ if (method.IsSpecialName)
+ mname = mname.Replace ("get_", "Get").Replace ("set_", "Set");
+
+ // it's possible that the selector was inlined for an OPTIONAL protocol member
+ // we do not want those reported (too many false positives) and we have other tests to find such mistakes
+ foreach (var intf in actualType.GetInterfaces ()) {
+ if (intf.GetCustomAttributes () == null)
+ continue;
+ var ext = Type.GetType (intf.Namespace + "." + intf.Name.Remove (0, 1) + "_Extensions, " + intf.Assembly.FullName);
+ if (ext == null)
+ continue;
+ foreach (var m in ext.GetMethods ()) {
+ if (mname != m.Name)
+ continue;
+ var parameters = method.GetParameters ();
+ var ext_params = m.GetParameters ();
+ // first parameters is `this XXX This`
+ if (parameters.Length == ext_params.Length - 1) {
+ bool match = true;
+ for (int i = 1; i < ext_params.Length; i++) {
+ match |= (parameters [i - 1].ParameterType == ext_params [i].ParameterType);
+ }
+ if (match)
+ return true;
+ }
+ }
+ }
+
+ name = actualType.FullName + " : " + name;
+ return false;
+ }
+
+ static IntPtr responds_handle = Selector.GetHandle ("instancesRespondToSelector:");
+
+ [Test]
+ public void Protocols ()
+ {
+ Errors = 0;
+ int n = 0;
+
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ foreach (object ca in t.GetCustomAttributes (false)) {
+ if (ca is ProtocolAttribute) {
+ foreach (var c in t.GetConstructors (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
+ ProcessProtocolMember (t, c, ref n);
+ }
+ foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
+ ProcessProtocolMember (t, m, ref n);
+ }
+ }
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} protocol selectors validated", Errors, n);
+ }
+
+ void ProcessProtocolMember (Type t, MethodBase m, ref int n)
+ {
+ if (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;
+
+ CheckInit (t, m, name);
+ n++;
+ }
+ }
+
+ protected virtual IntPtr GetClassForType (Type type)
+ {
+ var fi = type.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ if (fi == null)
+ return IntPtr.Zero; // e.g. *Delegate
+ return (IntPtr) fi.GetValue (null);
+ }
+
+ [Test]
+ public void InstanceMethods ()
+ {
+ Errors = 0;
+ int n = 0;
+
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ if (Skip (t) || SkipDueToAttribute (t))
+ continue;
+
+ IntPtr class_ptr = GetClassForType (t);
+
+ if (class_ptr == IntPtr.Zero)
+ continue;
+
+ foreach (var c in t.GetConstructors (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
+ Process (class_ptr, t, c, ref n);
+ }
+
+ foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
+ Process (class_ptr, t, m, ref n);
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} instance selector validated", Errors, n);
+ }
+
+ void Process (IntPtr class_ptr, Type t, MethodBase m, 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;
+
+ CheckInit (t, m, name);
+
+ bool result = bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name));
+ bool response = CheckResponse (result, t, m, ref name);
+ if (!response)
+ ReportError ("Selector not found for {0}", name);
+ n++;
+ }
+ }
+
+ void CheckInit (Type t, MethodBase m, string name)
+ {
+ if (SkipInit (name, m))
+ return;
+
+ bool init = IsInitLike (name);
+ if (m is ConstructorInfo) {
+ if (!init)
+ ReportError ("Selector {0} used on a constructor (not a method) on {1}", name, t.FullName);
+ } else {
+ if (init)
+ ReportError ("Selector {0} used on a method (not a constructor) on {1}", name, t.FullName);
+ }
+ }
+
+ bool IsInitLike (string selector)
+ {
+ if (!selector.StartsWith ("init", StringComparison.OrdinalIgnoreCase))
+ return false;
+ return selector.Length < 5 || Char.IsUpper (selector [4]);
+ }
+
+ protected virtual bool SkipInit (string selector, MethodBase m)
+ {
+ switch (selector) {
+ // NSAttributedString
+ case "initWithHTML:documentAttributes:":
+ case "initWithRTF:documentAttributes:":
+ case "initWithRTFD:documentAttributes:":
+ case "initWithURL:options:documentAttributes:error:":
+ case "initWithFileURL:options:documentAttributes:error:":
+ // AVAudioRecorder
+ case "initWithURL:settings:error:":
+ // NSUrlProtectionSpace
+ case "initWithHost:port:protocol:realm:authenticationMethod:":
+ case "initWithProxyHost:port:type:realm:authenticationMethod:":
+ // NSUserDefaults
+ case "initWithSuiteName:":
+ case "initWithUser:":
+ // GKScore
+ case "initWithCategory:":
+ case "initWithLeaderboardIdentifier:":
+ // MCSession
+ case "initWithPeer:securityIdentity:encryptionPreference:":
+ // UISegmentedControl
+ case "initWithItems:":
+ var mi = m as MethodInfo;
+ return mi != null && !mi.IsPublic && mi.ReturnType.Name == "IntPtr";
+ default:
+ return false;
+ }
+ }
+
+ protected virtual void Dispose (NSObject obj, Type type)
+ {
+ obj.Dispose ();
+ }
+
+ // funny, this is how I envisioned the instance version... before hitting run :|
+ protected virtual bool CheckStaticResponse (bool value, Type actualType, Type declaredType, ref string name)
+ {
+ if (value)
+ return true;
+
+ name = actualType.FullName + " : " + name;
+ return false;
+ }
+
+ [Test]
+ public void StaticMethods ()
+ {
+ Errors = 0;
+ int n = 0;
+
+ IntPtr responds_handle = Selector.GetHandle ("respondsToSelector:");
+
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ if (Skip (t) || SkipDueToAttribute (t))
+ continue;
+
+ FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ if (fi == null)
+ continue; // e.g. *Delegate
+ IntPtr class_ptr = (IntPtr) fi.GetValue (null);
+
+ foreach (var m in t.GetMethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)) {
+ if (SkipDueToAttribute (m))
+ continue;
+
+ foreach (object ca in m.GetCustomAttributes (true)) {
+ if (ca is ExportAttribute) {
+ string name = (ca as ExportAttribute).Selector;
+
+ if (Skip (t, name))
+ continue;
+
+ bool result = bool_objc_msgSend_IntPtr (class_ptr, responds_handle, Selector.GetHandle (name));
+ bool response = CheckStaticResponse (result, t, m.DeclaringType, ref name);
+ if (!response)
+ ReportError (name);
+ n++;
+ }
+ }
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} static selector validated", Errors, n);
+ }
+ }
+}
diff --git a/tests/bindings/ApiSignatureTest.cs b/tests/bindings/ApiSignatureTest.cs
new file mode 100644
index 000000000000..7582f2084bf0
--- /dev/null
+++ b/tests/bindings/ApiSignatureTest.cs
@@ -0,0 +1,760 @@
+//
+// Test the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Reflection;
+using System.Text;
+using NUnit.Framework;
+using System.Linq;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+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 string[] Split (string encoded, out int size)
+ {
+ List elements = new List ();
+ int pos = 0;
+ string s = Next (encoded, ref pos);
+ int end = pos;
+ while (Char.IsDigit (encoded [end]))
+ end++;
+
+ size = Int32.Parse (encoded.Substring (pos, end - pos));
+
+ if (encoded [end] != '@' || encoded [end + 1] != '0' || encoded [end + 2] != ':') {
+ if (!ContinueOnFailure)
+ Assert.Fail ("Unexpected format, missing '@0:', inside '{0}'", encoded);
+ return null;
+ }
+
+ pos = end + 3;
+
+ while (s != null) {
+ elements.Add (s);
+ s = Next (encoded, ref pos);
+ }
+ return elements.ToArray ();
+ }
+
+ static string Next (string encoded, ref int pos)
+ {
+ // skip digits
+ while (pos < encoded.Length && Char.IsDigit (encoded [pos]))
+ pos++;
+ if (pos >= encoded.Length)
+ return null;
+
+ StringBuilder sb = new StringBuilder ();
+ int acc = 0;
+ char c = encoded [pos];
+ while (!Char.IsDigit (c) || acc > 0) {
+ sb.Append (c);
+ if (c == '{' || c == '(')
+ acc++;
+ else if (c == '}' || c == ')')
+ acc--;
+ if (++pos >= encoded.Length)
+ break;
+ c = encoded [pos];
+ }
+ return sb.ToString ();
+ }
+
+ int TypeSize (Type t)
+ {
+ return TypeSize (t, ref t);
+ }
+
+ int TypeSize (Type t, ref Type real)
+ {
+ real = t;
+ if (!t.IsValueType)
+ return IntPtr.Size; // platform
+ if (t.IsEnum) {
+ foreach (var ca in t.CustomAttributes) {
+ if (ca.AttributeType.Name == "NativeAttribute")
+ return IntPtr.Size;
+ }
+ real = Enum.GetUnderlyingType (t);
+ }
+ return Marshal.SizeOf (real);
+ }
+
+ protected virtual int Size (Type t, bool simd = false)
+ {
+ switch (t.Name) {
+ // rdar 21375616 - Breaking change with EventKit[UI] enum base type
+ // EventKit.EK* enums are anonymous enums in 10.10 and iOS 8, but an NSInteger in 10.11 and iOS 9.
+ case "EKCalendarType":
+ case "EKParticipantType":
+ case "EKParticipantRole":
+ case "EKParticipantStatus":
+ case "EKEventStatus":
+ case "EKSourceType":
+ case "EKSpan":
+ case "EKRecurrenceFrequency":
+ case "EKEventAvailability":
+ if (!IsOSX11OrIOS9)
+ return 4;
+ break;
+ case "MDLAxisAlignedBoundingBox":
+ return 32; // struct (Vector3, Vector3)
+ }
+ if (simd) {
+ switch (t.Name) {
+ case "Vector3i": // sizeof (vector_uint3)
+ case "Vector3": // sizeof (vector_float3)
+ return 16;
+ case "MDLAxisAlignedBoundingBox":
+ return 32; // struct (Vector3, Vector3)
+ }
+ }
+ int size = TypeSize (t, ref t);
+ return t.IsPrimitive && size < 4 ? 4 : size;
+ }
+
+ protected virtual bool Skip (Type type)
+ {
+ if (type.ContainsGenericParameters)
+ return true;
+
+ return false;
+ }
+
+ protected virtual bool Skip (Type type, MethodBase method, string selector)
+ {
+ return SkipDueToAttribute (method);
+ }
+
+ public int CurrentParameter { get; private set; }
+
+ public MethodBase CurrentMethod { get; private set; }
+
+ public string CurrentSelector { get; private set; }
+
+ public Type CurrentType { get; private set; }
+
+ const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+
+ [Test]
+ public void Signatures ()
+ {
+ int n = 0;
+ Errors = 0;
+
+ foreach (Type t in Assembly.GetTypes ()) {
+
+ var static_type = t.IsSealed && t.IsAbstract; // e.g. [Category]
+ if (t.IsNested || (!static_type && !NSObjectType.IsAssignableFrom (t)))
+ continue;
+
+ if (Skip (t))
+ continue;
+
+ CurrentType = t;
+
+ FieldInfo fi = null;
+ if (!static_type)
+ fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ IntPtr class_ptr = fi == null ? IntPtr.Zero : (IntPtr) fi.GetValue (null);
+
+ foreach (MethodBase m in t.GetMethods (Flags))
+ CheckMemberSignature (m, t, class_ptr, ref n);
+ foreach (MethodBase m in t.GetConstructors (Flags))
+ CheckMemberSignature (m, t, class_ptr, ref n);
+ }
+ AssertIfErrors ("{0} errors found in {1} signatures validated", Errors, n);
+ }
+
+ void CheckMemberSignature (MethodBase m, Type t, IntPtr class_ptr, ref int n)
+ {
+ var methodinfo = m as MethodInfo;
+ var constructorinfo = m as ConstructorInfo;
+
+ if (methodinfo == null && constructorinfo == null)
+ return;
+
+ if (m.DeclaringType != t)
+ return;
+
+ CurrentMethod = m;
+
+ foreach (object ca in m.GetCustomAttributes (true)) {
+ var exportAttribute = ca as ExportAttribute;
+ if (exportAttribute == null)
+ continue;
+ string name = exportAttribute.Selector;
+
+ if (Skip (t, m, name))
+ continue;
+
+ CurrentSelector = name;
+
+ // in some cases, e.g. *Delegate, we cannot use introspection but we can still do some checks
+ if (class_ptr == IntPtr.Zero) {
+ BasicChecks (m, t, ref n);
+ } else {
+ IntrospectionTest (m, methodinfo, t, class_ptr, ref n);
+ }
+ }
+ }
+
+ void BasicChecks (MethodBase m, Type t, ref int n)
+ {
+ int native = 0;
+ int pos = CurrentSelector.IndexOf (':');
+ while (pos != -1) {
+ native++;
+ pos = CurrentSelector.IndexOf (':', pos + 1);
+ }
+ var mp = m.GetParameters ();
+ int managed = mp.Length;
+ if (t.IsSealed && t.IsAbstract) {
+ // static types, e.g. [Category], adds a first 'This' argument for extension methods
+ // but we also expose static properties this way, e.g. NSUrlUtilities_NSCharacterSet
+ if ((managed >= 1) && (mp [0].Name == "This"))
+ managed--;
+ }
+ if (LogProgress)
+ Console.WriteLine ("{0} {1} '{2}' selector {3} : {4} == {5}", ++n, t.Name, m, CurrentSelector, native, managed);
+ if (native != managed) {
+ AddErrorLine ("Parameter count mismatch for {0} in {1}:{2} : Native {3} vs Managed {4}",
+ CurrentSelector, t, m.Name, native, managed);
+ }
+ }
+
+ void IntrospectionTest (MethodBase m, MethodInfo methodinfo, Type t, IntPtr class_ptr, ref int n)
+ {
+ IntPtr sel = Selector.GetHandle (CurrentSelector);
+ IntPtr method;
+ if (methodinfo != null)
+ method = m.IsStatic ? class_getClassMethod (class_ptr, sel) : class_getInstanceMethod (class_ptr, sel);
+ else
+ 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, methodinfo != null ? methodinfo.IsStatic ? "static" : "instance" : "ctor", m, CurrentSelector, encoded);
+
+ // NSObject has quite a bit of stuff that's not usable (except by some class that inherits from it)
+ if (String.IsNullOrEmpty (encoded))
+ return;
+
+ int encoded_size = -1;
+ string [] elements = null;
+ try {
+ elements = Split (encoded, out encoded_size);
+ }
+ catch {
+ }
+ if (elements == null) {
+ if (LogProgress)
+ Console.WriteLine ("[WARNING] Could not parse encoded signature for {0} : {1}", CurrentSelector, encoded);
+ return;
+ }
+
+ bool result;
+ CurrentParameter = 0;
+
+ if (methodinfo != null) {
+ // check return value
+
+ result = Check (elements [CurrentParameter], methodinfo.ReturnType);
+ if (!result)
+ AddErrorLine ("Return Value of selector: {0} on type {1}, Type: {2}, Encoded as: {3}", CurrentSelector, t, methodinfo.ReturnType, elements [CurrentParameter]);
+ }
+
+ int size = 2 * IntPtr.Size; // self + selector (@0:)
+
+ var parameters = m.GetParameters ();
+ bool simd = (parameters.Length >= elements.Length);
+ foreach (var p in parameters) {
+ CurrentParameter++;
+ var pt = p.ParameterType;
+ if (CurrentParameter >= elements.Length) {
+ // SIMD structures are not (ios8 beta2) encoded in the signature, we ignore them
+ result = IgnoreSimd (CurrentSelector, t, pt);
+ if (!result)
+ AddErrorLine ("Selector: {0} on type {1}, Type: {2}, nothing encoded", CurrentSelector, t, pt);
+ } else {
+ // skip SIMD/vector parameters (as they are not encoded)
+ result = IgnoreSimd (CurrentSelector, t, pt);
+ if (result)
+ CurrentParameter--;
+ else
+ result = Check (elements [CurrentParameter], pt);
+ if (!result)
+ AddErrorLine ("Signature failure in {1} {0} Parameter '{4}' (#{5}) is encoded as '{3}' and bound as '{2}'",
+ CurrentSelector, t, pt, elements [CurrentParameter], p.Name, CurrentParameter);
+ }
+
+ size += Size (pt, simd);
+ }
+
+ // also ensure the encoded size match what MT (or XM) provides
+ // catch API errors (and should catch most 64bits issues as well)
+ if (size != encoded_size)
+ AddErrorLine ("Size {0} != {1} for {2} on {3}: {4}", encoded_size, size, CurrentSelector, t, encoded);
+ }
+
+ static bool IgnoreSimd (string name, Type t, Type pt)
+ {
+ switch (pt.Name) {
+ case "Vector2":
+ case "Vector2i":
+ case "Vector3":
+ case "Vector3i":
+ case "Vector4":
+ case "Vector4i":
+ case "MDLAxisAlignedBoundingBox": // struct { Vector3, Vector3 }
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected virtual bool IsValidStruct (Type type, string structName)
+ {
+ switch (structName) {
+ // MKPolygon 'static MonoTouch.MapKit.MKPolygon _FromPoints(IntPtr, Int32)' selector: polygonWithPoints:count: == @16@0:4^{?=dd}8I12
+ // NSValue 'static MonoTouch.Foundation.NSValue FromCMTime(CMTime)' selector: valueWithCMTime: == @32@0:4{?=qiIq}8
+ case "?":
+ return type.IsValueType; // || (type.FullName == "System.IntPtr");
+#if XAMCORE_2_0
+ case "CGRect":
+ return type.FullName == "CoreGraphics.CGRect";
+ case "CGSize":
+ return type.FullName == "CoreGraphics.CGSize";
+ case "CGPoint":
+ return type.FullName == "CoreGraphics.CGPoint";
+#else
+ case "CGRect":
+ return type.FullName == "System.Drawing.RectangleF";
+ case "CGSize":
+ return type.FullName == "System.Drawing.SizeF";
+ case "CGPoint":
+ return type.FullName == "System.Drawing.PointF";
+#endif
+ case "opaqueCMFormatDescription":
+ switch (type.Name) {
+ case "CMFormatDescription":
+ case "CMVideoFormatDescription":
+ case "CMAudioFormatDescription":
+ return true;
+ }
+ break;
+ case "opaqueCMSampleBuffer":
+ structName = "CMSampleBuffer";
+ break;
+ case "_NSRange":
+ structName = "NSRange";
+ break;
+ // textureWithContentsOfFile:options:queue:completionHandler: == v24@0:4@8@12^{dispatch_queue_s=}16@?20
+ case "dispatch_queue_s":
+ structName = "DispatchQueue";
+ break;
+ case "OpaqueCMClock":
+ structName = "CMClock";
+ break;
+ case "OpaqueCMTimebase":
+ structName = "CMTimebase";
+ break;
+ case "__CFRunLoop":
+ structName = "CFRunLoop";
+ break;
+ case "_GLKVector4":
+ structName = "Vector4";
+ break;
+ case "_GLKVector3":
+ structName = "Vector3";
+ break;
+ case "_GLKVector2":
+ structName = "Vector2";
+ break;
+ case "_GLKMatrix2":
+ structName = "Matrix2";
+ break;
+ case "_GLKMatrix3":
+ structName = "Matrix3";
+ break;
+ case "_GLKMatrix4":
+ structName = "Matrix4";
+ break;
+ case "__CVPixelBufferPool":
+ structName = "CVPixelBufferPool";
+ break;
+ case "opaqueMTAudioProcessingTap":
+ structName = "MTAudioProcessingTap";
+ break;
+ case "OpaqueMIDIEndpoint":
+ structName = "Int32";
+ break;
+ case "__CFDictionary":
+ structName = "NSDictionary";
+ break;
+ case "__CFUUID":
+ // CBAttribute.UUID is defined as a CBUUID but ObjC runtime tell us it's __CFUUID
+ // which makes it sound like a (undocumented) toll free bridged type
+ structName = "CBUUID";
+ break;
+ case "__CFString":
+ if (type.FullName == "System.String")
+ return true;
+ break;
+#if !MONOMAC
+ // definition is different on OSX
+ case "SCNVector4":
+ switch (type.Name) {
+ case "SCNVector4":
+ // typedef SCNVector4 SCNQuaternion; (SceneKitTypes.h)
+ case "SCNQuaternion":
+ return true;
+ }
+ break;
+#endif
+ case "_CGLContextObject":
+ structName = "CGLContext";
+ break;
+ case "_CGLPixelFormatObject":
+ structName = "CGLPixelFormat";
+ break;
+ case "OpaqueSecIdentityRef":
+ structName = "SecIdentity";
+ break;
+ case "__SecTrust":
+ structName = "SecTrust";
+ break;
+ case "_NSZone":
+ structName = "NSZone";
+ break;
+ case "_AVBeatRange":
+ structName = "AVBeatRange";
+ break;
+ case "AVAudio3DPoint":
+ structName = "Vector3";
+ break;
+ case "OpaqueMusicSequence":
+ structName = "MusicSequence";
+ break;
+ case "OpaqueAudioComponentInstance":
+ structName = "AudioUnit";
+ break;
+ case "OpaqueAudioComponent":
+ structName = "AudioComponent";
+ break;
+ case "GCQuaternion":
+ structName = "Quaterniond"; // OpenTK.Quaterniond
+ break;
+ case "OpaqueSecAccessControl": // El Capitan
+ case "__SecAccessControl":
+ structName = "SecAccessControl";
+ break;
+ case "AudioChannelLayout":
+ // this is actually an `nint` used as a pointer (to get a unique signature for the .ctor)
+ // there's custom code in src/AVFoundation/AVAudioChannelLayout.cs to deal with this
+#if XAMCORE_2_0
+ structName = "nint";
+#else
+ structName = "Int32";
+#endif
+ break;
+#if !XAMCORE_2_0
+ // in compat it's a class (instead of a struct) hence this hack
+ case "AudioComponentDescription":
+ structName = "AudioComponentDescriptionNative";
+ break;
+#endif
+ }
+ return type.Name == structName;
+ }
+
+ static Type inativeobject = typeof (INativeObject);
+
+ protected virtual bool Check (string encodedType, Type type)
+ {
+ char c = encodedType [0];
+
+ if (encodedType.Length == 1)
+ return Check (c, type);
+
+ switch (c) {
+ // GLKBaseEffect 'instance Vector4 get_LightModelAmbientColor()' selector: lightModelAmbientColor == (_GLKVector4={?=ffff}{?=ffff}{?=ffff}[4f])8@0:4
+ case '(':
+ case '{':
+ string struct_name = encodedType.Substring (1, encodedType.IndexOf ('=') - 1);
+ return IsValidStruct (type, struct_name);
+ case '@':
+ switch (encodedType [1]) {
+ case '?':
+ return (type.Name == "NSAction") || type.BaseType.FullName == "System.MulticastDelegate";
+ default:
+ return false;
+ }
+ case '^':
+ switch (encodedType [1]) {
+ case 'v':
+ // NSOpenGLContext 'instance MonoMac.OpenGL.CGLContext get_CGLContext()' selector: CGLContextObj == ^v8@0:4
+ if ((CurrentType.Name == "NSOpenGLContext") && (type.Name == "CGLContext"))
+ return true;
+ // NSOpenGLPixelFormat 'instance MonoMac.OpenGL.CGLPixelFormat get_CGLPixelFormat()' selector: CGLPixelFormatObj == ^v8@0:4
+ if ((CurrentType.Name == "NSOpenGLPixelFormat") && (type.Name == "CGLPixelFormat"))
+ return true;
+ if (type.Name == "ABRecord") {
+ if ((CurrentType.Name == "EKParticipant") || CurrentType.Name.StartsWith ("PKPayment", StringComparison.OrdinalIgnoreCase))
+ return true;
+ }
+ if ((type.Name == "ABAddressBook") && (CurrentType.Name == "EKParticipant"))
+ return true;
+ return (type.FullName == "System.IntPtr");
+ case 'B':
+ case 'd':
+ case 'f':
+ case 'I':
+ case 'i':
+ case 'c':
+ case 'q':
+ case 'Q':
+ case 'S':
+ return (type.FullName == "System.IntPtr") || Check (encodedType.Substring (1), type.GetElementType ());
+ // NSInputStream 'instance Boolean GetBuffer(IntPtr ByRef, UInt32 ByRef)' selector: getBuffer:length: == c16@0:4^*8^I12
+ case '*':
+ case '{':
+ // 10.7 only: NSArray 'static MonoMac.Foundation.NSArray FromObjects(IntPtr, Int32)' selector: arrayWithObjects:count: == @16@0:4^r@8I12
+ case 'r':
+ if (type.FullName == "System.IntPtr")
+ return true;
+ return Check (encodedType.Substring (1), type.IsByRef ? type.GetElementType () : type);
+ case '@':
+ return Check ('@', type.IsByRef ? type.GetElementType () : type);
+ case '^':
+ case '?':
+ return (type.FullName == "System.IntPtr");
+ default:
+ return false;
+ }
+ case 'r':
+ // const -> ignore
+ // e.g. vectorWithValues:count: == @16@0:4r^f8L12
+ case 'o':
+ // out -> ignore
+ // e.g. validateValue:forKey:error: == c20@0:4N^@8@12o^@16
+ case 'N':
+ // inout -> ignore
+ // e.g. validateValue:forKey:error: == c20@0:4N^@8@12o^@16
+ case 'V':
+ // oneway -> ignore
+ // e.g. NSObject 'instance Void NativeRelease()' selector: release == Vv8@0:4
+ return Check (encodedType.Substring (1), type);
+ default:
+ return false;
+ }
+ }
+
+ ///
+ /// Check that specified encodedType match the type and caller.
+ ///
+ /// Encoded type from the ObjC signature.
+ /// Managed type representing the encoded type.
+ /// Caller's type. Useful to limit any special case.
+ protected virtual bool Check (char encodedType, Type type)
+ {
+ switch (encodedType) {
+ case '@':
+ return (type.IsInterface || // protocol
+ type.IsArray || // NSArray
+ (type.Name == "NSArray") || // NSArray
+ (type.FullName == "System.String") || // NSString
+ (type.FullName == "System.IntPtr") || // unbinded, e.g. internal
+ (type.BaseType.FullName == "System.MulticastDelegate") || // completion handler -> delegate
+ NSObjectType.IsAssignableFrom (type)) || // NSObject derived
+ inativeobject.IsAssignableFrom (type); // e.g. CGImage
+ case 'B':
+ // 64 bits only encode this
+ return type.FullName == "System.Boolean";
+ case 'c': // char, used for C# bool
+ switch (type.FullName) {
+ case "System.Boolean":
+ case "System.SByte":
+ return true;
+ default:
+ return type.IsEnum && TypeSize (type) == 1;
+ }
+ case 'C':
+ switch (type.FullName) {
+ case "System.Byte":
+ // GLKBaseEffect 'instance Boolean get_ColorMaterialEnabled()' selector: colorMaterialEnabled == C8@0:4
+ case "System.Boolean":
+ return true;
+ default:
+ return false;
+ }
+ case 'd':
+ switch (type.FullName) {
+ case "System.Double":
+ return true;
+ case "System.nfloat":
+ return IntPtr.Size == 8;
+ default:
+ return false;
+ }
+ case 'f':
+ switch (type.FullName) {
+ case "System.Single":
+ return true;
+ case "System.nfloat":
+ return IntPtr.Size == 4;
+ default:
+ return false;
+ }
+ case 'i':
+ switch (type.FullName) {
+ case "System.Int32":
+ return true;
+ case "System.nint":
+ return IntPtr.Size == 4;
+ case "EventKit.EKSourceType":
+ case "EventKit.EKCalendarType":
+ case "EventKit.EKEventAvailability":
+ case "EventKit.EKEventStatus":
+ case "EventKit.EKParticipantRole":
+ case "EventKit.EKParticipantStatus":
+ case "EventKit.EKParticipantType":
+ case "EventKit.EKRecurrenceFrequency":
+ case "EventKit.EKSpan":
+ case "EventKit.EKAlarmType":
+ // EventKit.EK* enums are anonymous enums in 10.10 and iOS 8, but an NSInteger in 10.11 and iOS 9.
+ if (IsOSX11OrIOS9)
+ goto default;
+ return true;
+ default:
+ return type.IsEnum && TypeSize (type) == 4;
+ }
+ case 'I':
+ switch (type.FullName) {
+ case "System.UInt32":
+ return true;
+ case "System.nint": // check
+ case "System.nuint":
+ return IntPtr.Size == 4;
+ default:
+ return type.IsEnum && TypeSize (type) == 4;
+ }
+ case 'l':
+ switch (type.FullName) {
+ case "System.Int32":
+ return true;
+ case "System.nint":
+ return IntPtr.Size == 4;
+ default:
+ return type.IsEnum && TypeSize (type) == 4;
+ }
+ case 'L':
+ switch (type.FullName) {
+ case "System.UInt32":
+ return true;
+ case "System.nint": // check
+ case "System.nuint":
+ return IntPtr.Size == 4;
+ default:
+ return type.IsEnum && TypeSize (type) == 4;
+ }
+ case 'q':
+ switch (type.FullName) {
+ case "System.Int64":
+ return true;
+ case "System.nint":
+ return IntPtr.Size == 8;
+ default:
+ return type.IsEnum && TypeSize (type) == 8;
+ }
+ case 'Q':
+ switch (type.FullName) {
+ case "System.UInt64":
+ return true;
+ case "System.nint": // check
+ case "System.nuint":
+ return IntPtr.Size == 8;
+ default:
+ return type.IsEnum && TypeSize (type) == 8;
+ }
+ case 's':
+ return type.FullName == "System.Int16";
+ // unsigned 16 bits
+ case 'S':
+ switch (type.FullName) {
+ case "System.UInt16":
+ // NSString 'instance Char _characterAtIndex(Int32)' selector: characterAtIndex: == S12@0:4I8
+ case "System.Char":
+ return true;
+ default:
+ return type.IsEnum && TypeSize (type) == 2;
+ }
+ case ':':
+ return type.Name == "Selector";
+ case 'v':
+ return type.FullName == "System.Void";
+ case '?':
+ return type.BaseType.FullName == "System.MulticastDelegate"; // completion handler -> delegate
+ case '#':
+ return type.FullName == "System.IntPtr" || type.Name == "Class";
+ // CAMediaTimingFunction 'instance Void GetControlPointAtIndex(Int32, IntPtr)' selector: getControlPointAtIndex:values: == v16@0:4L8[2f]12
+ case '[':
+ return type.FullName == "System.IntPtr";
+ // const uint8_t * -> IntPtr
+ // NSCoder 'instance Void EncodeBlock(IntPtr, Int32, System.String)' selector: encodeBytes:length:forKey: == v20@0:4r*8I12@16
+ case '*':
+ return type.FullName == "System.IntPtr";
+ case '^':
+ return type.FullName == "System.IntPtr";
+ }
+ return false;
+ }
+ }
+}
diff --git a/tests/bindings/ApiStructTest.cs b/tests/bindings/ApiStructTest.cs
new file mode 100644
index 000000000000..de06a491f7b8
--- /dev/null
+++ b/tests/bindings/ApiStructTest.cs
@@ -0,0 +1,95 @@
+//
+// ApiStructTest.cs: enforce structure definitions
+//
+// Authors:
+// Aaron Bockover
+//
+// Copyright 2013 Xamarin, Inc.
+
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using ObjCRuntime;
+using Foundation;
+#elif MONOMAC
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+#endif
+
+namespace TouchUnit.Bindings
+{
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class ApiStructTest : ApiBaseTest
+ {
+ public ApiStructTest ()
+ {
+ ContinueOnFailure = true;
+ LogProgress = true;
+ }
+
+ protected virtual bool Skip (Type type)
+ {
+ return SkipDueToAttribute (type);
+ }
+
+ [Test]
+ public void Structs ()
+ {
+ int totalStructs = 0;
+ int totalErrors = 0;
+
+ var structQuery = from type in Assembly.GetTypes ()
+ where type.IsValueType && !type.IsPrimitive && !type.IsEnum && !Skip (type)
+ select type;
+
+ foreach (var type in structQuery) {
+ totalStructs++;
+ if (!CheckStruct (type)) {
+ totalErrors++;
+
+ if (!ContinueOnFailure)
+ break;
+ }
+ }
+
+ Assert.AreEqual (0, totalErrors,
+ "{0} errors found in {1} structures validated",
+ totalErrors, totalStructs);
+ }
+
+ protected virtual bool CheckStruct (Type type)
+ {
+ var success = true;
+
+ foreach (var fi in type.GetFields ()) {
+ if (!CheckField (type, fi))
+ success = false;
+ }
+
+ return success;
+ }
+
+ protected virtual bool CheckField (Type type, FieldInfo fi)
+ {
+#if XAMCORE_2_0
+ if (fi.FieldType.IsEnum && fi.FieldType.GetCustomAttribute () != null) {
+ if (LogProgress)
+ Console.Error.WriteLine ("{0} has a [Native] enum field in its definition: {1} {2}",
+ type.FullName, fi.FieldType, fi.Name);
+ return false;
+ }
+#endif
+ return true;
+ }
+ }
+}
+
diff --git a/tests/bindings/ApiWeakPropertyTest.cs b/tests/bindings/ApiWeakPropertyTest.cs
new file mode 100644
index 000000000000..4c07b26a5d95
--- /dev/null
+++ b/tests/bindings/ApiWeakPropertyTest.cs
@@ -0,0 +1,110 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Reflection;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+ [Preserve (AllMembers = true)]
+ public abstract class ApiWeakPropertyTest : ApiBaseTest {
+
+ ///
+ /// Override if you want to skip testing the specified type.
+ ///
+ /// Type to be tested
+ protected virtual bool Skip (Type type)
+ {
+ switch (type.Name) {
+ case "LinkWithAttribute": // LinkWithAttribute.WeakFrameworks
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Override if you want to skip testing the specified property.
+ ///
+ /// Property candidate.
+ protected virtual bool Skip (PropertyInfo property)
+ {
+ return false;
+ }
+
+ [Test]
+ public void WeakPropertiesHaveArgumentSemantic ()
+ {
+ var failed_properties = new List ();
+
+ Errors = 0;
+ int c = 0, n = 0;
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (Skip (t) || SkipDueToAttribute (t))
+ continue;
+
+ if (LogProgress)
+ Console.WriteLine ("{0}. {1}", c++, t.FullName);
+
+ foreach (var p in t.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
+ // looking for properties with setters only
+ if (!p.CanWrite)
+ continue;
+
+ if (SkipDueToAttribute (p))
+ continue;
+
+ if (Skip (p))
+ continue;
+
+ string name = p.Name;
+ if (!name.StartsWith ("Weak"))
+ continue;
+
+ string error;
+ if (CheckArgumentSemantic (p.GetMethod, out error)) {
+ ReportError (error);
+ failed_properties.Add (p.ToString ());
+ }
+ if (CheckArgumentSemantic (p.SetMethod, out error)) {
+ ReportError (error);
+ failed_properties.Add (p.ToString ());
+ }
+ n++;
+ }
+ }
+ Assert.AreEqual (0, Errors, "{0} errors found in {1} fields validated: {2}", Errors, n, string.Join (", ", failed_properties));
+ }
+
+ bool CheckArgumentSemantic (MethodInfo meth, out string error)
+ {
+ error = null;
+ var export = meth.GetCustomAttribute ();
+ if (export == null) {
+ error = String.Format ("{0}.{1} has no [Export]", meth.DeclaringType.FullName, meth.Name);
+ return true;
+ }
+
+ switch (export.ArgumentSemantic) {
+ case ArgumentSemantic.Assign: // Also case ArgumentSemantic.UnsafeUnretained:
+ case ArgumentSemantic.Copy:
+ case ArgumentSemantic.Retain: // case ArgumentSemantic.Strong:
+ case ArgumentSemantic.Weak:
+ return false;
+ default:
+ error = String.Format ("{0}.{1} has incorrect ArgumentSemantics: {2}", meth.DeclaringType.FullName, meth.Name, export.ArgumentSemantic);
+ return true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/bindings/CoreSelectorTest.cs b/tests/bindings/CoreSelectorTest.cs
new file mode 100644
index 000000000000..12204505a3a9
--- /dev/null
+++ b/tests/bindings/CoreSelectorTest.cs
@@ -0,0 +1,130 @@
+//
+// Test the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+
+ public abstract class CoreSelectorTest : ApiSelectorTest {
+
+ protected override bool CheckResponse (bool value, Type actualType, MethodBase method, ref string name)
+ {
+ if (value)
+ return true;
+
+ var declaredType = method.DeclaringType;
+
+ switch (name) {
+ // optional stuff defined in NSObject (but not implemented by every subclasses)
+ case "encodeWithCoder:":
+ case "objectDidEndEditing:":
+ case "commitEditing":
+ case "commitEditingWithDelegate:didCommitSelector:contextInfo:":
+ if (declaredType.Name == "NSObject")
+ return true;
+ break;
+ // internal stuff that must be used
+ case "_setCFClientFlags:callback:context:":
+ case "_scheduleInCFRunLoop:forMode:":
+ case "_unscheduleFromCFRunLoop:forMode:":
+ // init* works (see monotouchtest.app) but does not respond when queried
+ case "initWithFileAtPath:":
+ case "initWithData:":
+ case "initWithURL:":
+ if (declaredType.Name == "NSInputStream")
+ return true;
+ break;
+ // init* works (see monotouchtest.app) but does not respond when queried
+ case "initToMemory":
+ case "initToFileAtPath:append:":
+ if (declaredType.Name == "NSOutputStream")
+ return true;
+ break;
+ // init* works (see monotouchtest.app) but does not respond when queried
+ case "initWithFileDescriptor:":
+ case "initWithFileDescriptor:closeOnDealloc:":
+ if (declaredType.Name == "NSFileHandle")
+ return true;
+ break;
+ case "initWithString:":
+ case "initWithString:attributes:":
+ case "initWithAttributedString:":
+ if (declaredType.Name == "NSAttributedString" || declaredType.Name == "NSMutableAttributedString")
+ return true;
+ break;
+ }
+ return base.CheckResponse (value, actualType, method, ref name);
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.Name) {
+ case "MTLRenderPassAttachmentDescriptor":
+ // This is an abstract(-ish...) type, iOS allows creating an instance of it, but the instance doesn't respond to most of the selector in the headers.
+ return true;
+ }
+
+ return base.Skip (type);
+ }
+
+ protected override IntPtr GetClassForType (Type type)
+ {
+ switch (type.Namespace) {
+ case "MonoTouch.Metal":
+ case "MonoMac.Metal":
+ case "Metal":
+ switch (type.Name) {
+ case "MTLArgument":
+ case "MTLArrayType":
+ case "MTLCompileOptions":
+ case "MTLComputePipelineDescriptor":
+ case "MTLComputePipelineReflection":
+ case "MTLDepthStencilDescriptor":
+ case "MTLRenderPassAttachmentDescriptor":
+ case "MTLRenderPassColorAttachmentDescriptor":
+ case "MTLRenderPassDepthAttachmentDescriptor":
+ case "MTLRenderPassDescriptor":
+ case "MTLRenderPassStencilAttachmentDescriptor":
+ case "MTLRenderPipelineColorAttachmentDescriptor":
+ case "MTLRenderPipelineDescriptor":
+ case "MTLRenderPipelineReflection":
+ case "MTLSamplerDescriptor":
+ case "MTLStencilDescriptor":
+ case "MTLStructMember":
+ case "MTLStructType":
+ case "MTLTextureDescriptor":
+ case "MTLVertexAttribute":
+ case "MTLVertexAttributeDescriptor":
+ case "MTLVertexBufferLayoutDescriptor":
+ case "MTLVertexDescriptor":
+ var ctor = type.GetConstructor (Type.EmptyTypes);
+ using (var obj = ctor.Invoke (null) as NSObject) {
+ return IntPtr_objc_msgSend (obj.Handle, Selector.GetHandle ("class"));
+ }
+ }
+ break;
+ }
+
+ return base.GetClassForType (type);
+ }
+ }
+}
diff --git a/tests/bindings/PlatformInfo.cs b/tests/bindings/PlatformInfo.cs
new file mode 100644
index 000000000000..391865f997fd
--- /dev/null
+++ b/tests/bindings/PlatformInfo.cs
@@ -0,0 +1,151 @@
+//
+// PlatformInfo.cs: info about the host platform
+// and AvailabilityBaseAttribute extensions for tests
+//
+// Author:
+// Aaron Bockover
+//
+// Copyright 2015 Xamarin Inc. All rights reserved.
+
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Collections.Generic;
+
+#if XAMCORE_2_0
+using ObjCRuntime;
+using Foundation;
+#if !MONOMAC
+using UIKit;
+#endif
+#elif MONOMAC
+using MonoMac.ObjCRuntime;
+using MonoMac.Foundation;
+#else
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+
+namespace TouchUnit.Bindings
+{
+ public sealed class PlatformInfo
+ {
+ static PlatformInfo GetHostPlatformInfo ()
+ {
+ string name;
+ string version;
+#if __TVOS__ || __IOS__
+ name = UIDevice.CurrentDevice.SystemName;
+ version = UIDevice.CurrentDevice.SystemVersion;
+#elif __WATCHOS__
+ name = WatchKit.WKInterfaceDevice.CurrentDevice.SystemName;
+ version = WatchKit.WKInterfaceDevice.CurrentDevice.SystemVersion;
+#elif MONOMAC
+ using (var plist = NSDictionary.FromFile ("/System/Library/CoreServices/SystemVersion.plist")) {
+ name = (NSString)plist ["ProductName"];
+ version = (NSString)plist ["ProductVersion"];
+ }
+#else
+#error Unknown platform
+#endif
+ name = name?.Replace (" ", String.Empty)?.ToLowerInvariant ();
+
+ var platformInfo = new PlatformInfo ();
+
+ if (name != null && name.StartsWith ("mac", StringComparison.Ordinal))
+ platformInfo.Name = PlatformName.MacOSX;
+ else if (name != null && (name.StartsWith ("ios", StringComparison.Ordinal) || name.StartsWith ("iphoneos", StringComparison.Ordinal)))
+ platformInfo.Name = PlatformName.iOS;
+ else if (name != null && name.StartsWith ("tvos", StringComparison.Ordinal))
+ platformInfo.Name = PlatformName.TvOS;
+ else if (name != null && name.StartsWith ("watchos", StringComparison.Ordinal))
+ platformInfo.Name = PlatformName.WatchOS;
+ else
+ throw new FormatException ($"Unknown product name: {name}");
+
+ platformInfo.Version = Version.Parse (version);
+
+ if (IntPtr.Size == 4)
+ platformInfo.Architecture = PlatformArchitecture.Arch32;
+ else if (IntPtr.Size == 8)
+ platformInfo.Architecture = PlatformArchitecture.Arch64;
+
+ return platformInfo;
+ }
+
+ public static readonly PlatformInfo Host = GetHostPlatformInfo ();
+
+ public PlatformName Name { get; private set; }
+ public PlatformArchitecture Architecture { get; private set; }
+ public Version Version { get; private set; }
+
+ public bool IsMac => Name == PlatformName.MacOSX;
+ public bool IsIos => Name == PlatformName.iOS;
+ public bool IsArch32 => Architecture.HasFlag (PlatformArchitecture.Arch32);
+ public bool IsArch64 => Architecture.HasFlag (PlatformArchitecture.Arch64);
+
+ PlatformInfo ()
+ {
+ }
+ }
+
+ public static class AvailabilityExtensions
+ {
+ public static bool IsAvailableOnHostPlatform (this ICustomAttributeProvider attributeProvider)
+ {
+ return attributeProvider.IsAvailable (PlatformInfo.Host);
+ }
+
+ public static bool IsAvailable (this ICustomAttributeProvider attributeProvider, PlatformInfo targetPlatform)
+ {
+ return attributeProvider
+ .GetCustomAttributes (true)
+ .OfType ()
+ .IsAvailable (targetPlatform);
+ }
+
+ public static bool IsAvailableOnHostPlatform (this IEnumerable attributes)
+ {
+ return attributes.IsAvailable (PlatformInfo.Host);
+ }
+
+ public static bool IsAvailable (this IEnumerable attributes, PlatformInfo targetPlatform)
+ {
+ // always "available" from a binding perspective if
+ // there are no explicit annotations saying otherwise
+ var available = true;
+
+ foreach (var attr in attributes) {
+ if (attr.Platform != targetPlatform.Name)
+ continue;
+
+ switch (attr.AvailabilityKind) {
+ case AvailabilityKind.Introduced:
+ if (attr.Version != null)
+ available &= targetPlatform.Version >= attr.Version;
+
+ if (attr.Architecture != PlatformArchitecture.None &&
+ attr.Architecture != PlatformArchitecture.All)
+ available &= attr.Architecture.HasFlag (targetPlatform.Architecture);
+ break;
+ case AvailabilityKind.Deprecated:
+ case AvailabilityKind.Obsoleted:
+ if (attr.Version != null)
+ available &= targetPlatform.Version < attr.Version;
+ // FIXME: handle architecture-level _un_availability?
+ // we didn't do this with the old AvailabilityAttribute...
+ break;
+ case AvailabilityKind.Unavailable:
+ available = false;
+ break;
+ }
+
+ if (!available)
+ return false;
+ }
+
+ return available;
+ }
+ }
+}
diff --git a/tests/bindings/README b/tests/bindings/README
new file mode 100644
index 000000000000..47c3f09627c2
--- /dev/null
+++ b/tests/bindings/README
@@ -0,0 +1 @@
+Unit test helpers for developers of MonoTouch and Xamarin.Mac binding libraries
\ No newline at end of file
diff --git a/tests/common.mk b/tests/common.mk
new file mode 100644
index 000000000000..6b3eecafeaaf
--- /dev/null
+++ b/tests/common.mk
@@ -0,0 +1,76 @@
+MMP=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/bin/mmp $(MMP_VERBOSITY)
+
+.PRECIOUS: build/mobile-32.app build/mobile-64.app
+
+check-guiunit-xml:
+ @if test -f $(FILE); then \
+ if grep 'One or more child tests had errors' $(FILE) > /dev/null; then \
+ echo Test run failed; \
+ exit 1; \
+ fi; \
+ echo Test run succeeded; \
+ else \
+ echo Test run crashed; \
+ exit 1; \
+ fi
+
+BASE_DLLS = $(TOP)/src/build/mac/compat/XamMac.dll \
+ $(TOP)/src/build/mac/mobile-32/Xamarin.Mac.dll \
+ $(TOP)/src/build/mac/mobile-64/Xamarin.Mac.dll
+
+all-local:: build/compat/$(TESTDLL) build/mobile-32/$(TESTDLL) build/mobile-64/$(TESTDLL)
+
+clean-local::
+ rm -rf build TestResult*.xml
+
+build/%/$(TESTDLL): $(MAC_SOURCES) build/GuiUnit.exe Makefile $(BASE_DLLS)
+ @mkdir -p $(dir $@)
+ $(Q_MCS) $(SYSTEM_MCS) -out:$@ -t:library -debug -d:MONOMAC -d:XAMCORE_2_0 \
+ -r:build/GuiUnit.exe \
+ -r:$(TOP)/src/build/mac/$*/Xamarin.Mac.dll \
+ $(MAC_SOURCES)
+
+build/compat/$(TESTDLL): $(MAC_SOURCES) build/GuiUnit.exe Makefile $(BASE_DLLS)
+ @mkdir -p $(dir $@)
+ $(Q_MCS) $(SYSTEM_MCS) -out:$@ -t:library -debug -d:MONOMAC \
+ -r:build/GuiUnit.exe \
+ -r:System.Drawing \
+ -r:$(TOP)/src/build/mac/compat/XamMac.dll \
+ $(MAC_SOURCES)
+
+build/compat.app: build/compat/$(TESTDLL) $(BASE_DLLS)
+ @rm -Rf $@
+ $(Q) DEVELOPER_DIR=$(XCODE_DEVELOPER_ROOT) $(MMP) --output $(abspath build/compat.app) $(abspath build/GuiUnit.exe) -a $(TOP)/src/build/mac/compat/XamMac.dll --nolink --profile 4.5 --cache $(abspath build/compat-mmp-cache) --marshal-objectivec-exceptions=throwmanaged
+
+build/mobile-%.app: build/mobile-%/$(TESTDLL) $(BASE_DLLS)
+ @rm -Rf $@
+ $(Q) DEVELOPER_DIR=$(XCODE_DEVELOPER_ROOT) $(MMP) --output $(abspath build/mobile-$*.app) $(abspath build/GuiUnit.exe) -a $(TOP)/src/build/mac/mobile-$*/Xamarin.Mac.dll --nolink --profile mobile --arch $(shell test '$*' == '32' && echo i386 || echo x86_64) --cache $(abspath build/mobile-$*-mmp-cache) --marshal-objectivec-exceptions=throwmanaged
+
+exec-compat: build/compat.app
+ @rm -f TestResult-compat.xml
+ build/compat.app/GuiUnit.app/Contents/MacOS/GuiUnit -noheader $(abspath build/compat/$(TESTDLL)) -xml:$(PWD)/TestResult-compat.xml
+ @test -z "$(BUILD_REVISION)" || echo @"MonkeyWrench: AddFile: $(abspath TestResult-compat.xml)"
+ @$(MAKE) check-guiunit-xml FILE=TestResult-compat.xml STAMP=.$@-failure.stamp
+
+exec-mobile-%: build/mobile-%.app
+ @rm -f TestResult-mobile-$*.xml .$@-failure.stamp
+ build/mobile-$*.app/GuiUnit.app/Contents/MacOS/GuiUnit -noheader $(abspath build/mobile-$*/$(TESTDLL)) -xml:$(PWD)/TestResult-mobile-$*.xml
+ @test -z "$(BUILD_REVISION)" || echo @"MonkeyWrench: AddFile: $(abspath TestResult-mobile-$*.xml)"
+ @$(MAKE) check-guiunit-xml FILE=TestResult-mobile-$*.xml STAMP=.$@-failure.stamp
+
+run-%:
+ @rm -f .$@-failure.stamp
+ @$(MAKE) exec-$* || echo "run-$* failed" >> .$@-failure.stamp
+ @if test -e .$@-failure.stamp; then cat .$@-failure.stamp; rm .$@-failure.stamp; exit 1; fi
+
+run run-test run-tests: build/compat.app build/mobile-32.app build/mobile-64.app
+ @rm -f .$@-failure.stamp
+ @$(MAKE) exec-compat || echo "run-compat failed" >> .$@-failure.stamp
+ @$(MAKE) exec-mobile-32 || echo "run-mobile-32 failed" >> .$@-failure.stamp
+ @$(MAKE) exec-mobile-64 || echo "run-mobile-64 failed" >> .$@-failure.stamp
+ @if test -e .$@-failure.stamp; then cat .$@-failure.stamp; rm .$@-failure.stamp; exit 1; fi
+
+build/GuiUnit.exe: $(shell find $(GUI_UNIT_PATH)/src/framework -name \*.cs -or -name \*.csproj)
+ @mkdir -p build
+ @$(SYSTEM_XBUILD) $(GUI_UNIT_PATH)/src/framework/GuiUnit_NET_4_5.csproj
+ @cp $(GUI_UNIT_PATH)/bin/net_4_5/GuiUnit.exe $@
diff --git a/tests/common/Assert.cs b/tests/common/Assert.cs
new file mode 100644
index 000000000000..824d01b58152
--- /dev/null
+++ b/tests/common/Assert.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Resources;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+using NUnit.Framework;
+using NUnit.Framework.Constraints;
+
+namespace MonoTests {
+/*
+ class CategoryAttribute : Attribute
+ {
+ public string Category { get; set; }
+
+ public CategoryAttribute (string category)
+ {
+ this.Category = category;
+ }
+ }
+/*
+ static class Assert
+ {
+ public static void AreEqual (object a, object b, string msg)
+ {
+ NUnit.Framework.Assert.That (a, Is.EqualTo (b), msg);
+ }
+
+ public static void AreEqual (object a, object b)
+ {
+ NUnit.Framework.Assert.That (a, Is.EqualTo (b));
+ }
+
+ public static void IsNotNull (object o, string msg)
+ {
+ NUnit.Framework.Assert.That (o, Is.Not.Null, msg);
+ }
+
+ public static void IsNotNull (object o)
+ {
+ NUnit.Framework.Assert.That (o, Is.Not.Null);
+ }
+
+ public static void IsNull (object o, string msg)
+ {
+ NUnit.Framework.Assert.That (o, Is.Null, msg);
+ }
+
+ public static void IsNull (object o)
+ {
+ NUnit.Framework.Assert.That (o, Is.Null);
+ }
+
+ public static void IsTrue (object o, string msg)
+ {
+ NUnit.Framework.Assert.That (o, Is.True, msg);
+ }
+
+ public static void IsTrue (object o)
+ {
+ NUnit.Framework.Assert.That (o, Is.True);
+ }
+
+ public static void IsFalse (object o, string msg)
+ {
+ NUnit.Framework.Assert.That (o, Is.False, msg);
+ }
+
+ public static void IsFalse (object o)
+ {
+ NUnit.Framework.Assert.That (o, Is.False);
+ }
+
+ public static void AreSame (object a, object b)
+ {
+ NUnit.Framework.Assert.That (a, Is.SameAs (b));
+ }
+
+ public static void AreSame (object a, object b, string msg)
+ {
+ NUnit.Framework.Assert.That (a, Is.SameAs (b), msg);
+ }
+
+ public static void Fail (string msg)
+ {
+ NUnit.Framework.Assert.Fail (msg);
+ }
+ }
+*/
+ // nunit 1.x compatibility
+ public class TestCase {
+ protected virtual void SetUp ()
+ {
+ }
+
+ public static void Assert (string msg, bool condition)
+ {
+ NUnit.Framework.Assert.True (condition, msg);
+ }
+
+ public static void AssertEquals (object a, object b)
+ {
+ NUnit.Framework.Assert.That (a, Is.EqualTo (b));
+ }
+
+ public static void AssertEquals (string msg, object a, object b)
+ {
+ NUnit.Framework.Assert.That (a, Is.EqualTo (b), msg);
+ }
+
+ public static void AssertNull (object a)
+ {
+ NUnit.Framework.Assert.That (a, Is.Null);
+ }
+
+ public static void AssertNull (string msg, object a)
+ {
+ NUnit.Framework.Assert.That (a, Is.Null, msg);
+ }
+
+ public static void AssertNotNull (object a)
+ {
+ NUnit.Framework.Assert.That (a, Is.Not.Null);
+ }
+
+ public static void AssertNotNull (string msg, object a)
+ {
+ NUnit.Framework.Assert.That (a, Is.Not.Null, msg);
+ }
+
+ public static void Fail (string msg)
+ {
+ NUnit.Framework.Assert.Fail (msg);
+ }
+ }
+
+ public class Assertion : TestCase {
+ }
+
+ public class TestFixtureSetUpAttribute : SetUpAttribute {
+ }
+
+ public class StringAssert {
+ #region StartsWith
+ static public void StartsWith(string expected, string actual, string message, params object[] args)
+ {
+ Assert.That(actual, new StartsWithConstraint(expected), message, args);
+ }
+
+ static public void StartsWith(string expected, string actual, string message)
+ {
+ StartsWith(expected, actual, message, null);
+ }
+
+ static public void StartsWith(string expected, string actual)
+ {
+ StartsWith(expected, actual, string.Empty, null);
+ }
+ #endregion
+
+ #region Contains
+ static public void Contains(string expected, string actual, string message, params object[] args)
+ {
+ Assert.That(actual, new SubstringConstraint(expected), message, args);
+ }
+
+ static public void Contains(string expected, string actual, string message)
+ {
+ Contains(expected, actual, message, null);
+ }
+
+ static public void Contains(string expected, string actual)
+ {
+ Contains(expected, actual, string.Empty, null);
+ }
+ #endregion
+ }
+}
+
diff --git a/tests/common/AssertHelpers.cs b/tests/common/AssertHelpers.cs
new file mode 100644
index 000000000000..35c7ee5ba6e4
--- /dev/null
+++ b/tests/common/AssertHelpers.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using NUnit.Framework;
+
+namespace Xamarin.Tests
+{
+ public delegate void Action ();
+
+ public static class Asserts
+ {
+ public static void Throws (Action action, string expectedExceptionMessage, string message = "") where T: Exception
+ {
+ try {
+ action ();
+ throw new AssertionException (string.Format ("Expected {0}, but no exception was thrown. {1}.", typeof (T).FullName, message));
+ } catch (T ex) {
+ Assert.AreEqual (expectedExceptionMessage, ex.Message, message);
+ }
+ }
+
+ public static void ThrowsPartial (Action action, string [] expectedExceptionMessages, string message = "") where T: Exception
+ {
+ try {
+ action ();
+ throw new AssertionException (string.Format ("Expected {0}, but no exception was thrown. {1}.", typeof (T).FullName, message));
+ } catch (T ex) {
+ string [] actual = ex.Message.Split (new string [] { Environment.NewLine }, StringSplitOptions.None);
+ for (int i = 0; i < expectedExceptionMessages.Length; i++)
+ StartsWith (expectedExceptionMessages [i], actual [i], i.ToString ());
+ }
+ }
+
+ public static void ThrowsPattern (Action action, string expectedExceptionPattern, string message = "") where T: Exception
+ {
+ try {
+ action ();
+ throw new AssertionException (string.Format ("Expected {0}, but no exception was thrown. {1}.", typeof (T).FullName, message));
+ } catch (T ex) {
+ IsLike (expectedExceptionPattern, ex.Message, message);
+ }
+ }
+
+ public static void StartsWith (string expectedStartsWith, string actual, string message)
+ {
+ if (!actual.StartsWith (expectedStartsWith))
+ throw new AssertionException (string.Format ("Expected '{0}' to start with '{1}'. {2}", actual, expectedStartsWith, message));
+ }
+
+ public static void IsLike (string pattern, string actual, string message)
+ {
+ if (!Regex.IsMatch (actual, pattern, RegexOptions.CultureInvariant))
+ throw new AssertionException (string.Format ("Expected '{0}' to match pattern '{1}'. {2}", actual, pattern, message));
+ }
+
+ public static void Contains (string expectedToContain, string actual, string message)
+ {
+ if (!actual.Contains (expectedToContain))
+ throw new AssertionException (string.Format ("Expected '{0}' to contain '{1}'. {2}", actual, expectedToContain, message));
+ }
+
+ public static void DoesNotContain (string expectedToNotContain, string actual, string message)
+ {
+ if (actual.Contains (expectedToNotContain))
+ throw new AssertionException (string.Format ("Did not expect '{0}' to contain '{1}'. {2}", actual, expectedToNotContain, message));
+ }
+ }
+}
+
diff --git a/tests/common/ExecutionHelper.cs b/tests/common/ExecutionHelper.cs
new file mode 100644
index 000000000000..19c1fc2bdbd4
--- /dev/null
+++ b/tests/common/ExecutionHelper.cs
@@ -0,0 +1,311 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Diagnostics;
+
+using NUnit.Framework;
+
+namespace Xamarin.Tests
+{
+ class ToolMessage
+ {
+ public bool IsError;
+ public bool IsWarning { get { return !IsError; } }
+ public string Prefix;
+ public int Number;
+ public string PrefixedNumber { get { return Prefix + Number.ToString (); } }
+ public string Message;
+ // public string Filename;
+ // public int LineNumber;
+ }
+
+ class Tool
+ {
+ StringBuilder output = new StringBuilder ();
+
+ List output_lines;
+
+ List messages = new List ();
+
+ public Dictionary EnvironmentVariables { get; set; }
+ public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds (60);
+
+ public IEnumerable Messages { get { return messages; } }
+ List OutputLines {
+ get {
+ if (output_lines == null) {
+ output_lines = new List ();
+ output_lines.AddRange (output.ToString ().Split ('\n'));
+ }
+ return output_lines;
+ }
+ }
+
+ public int Execute (string arguments, params string [] args)
+ {
+ output.Clear ();
+ output_lines = null;
+
+ var rv = ExecutionHelper.Execute (TestTarget.ToolPath, string.Format (arguments, args), EnvironmentVariables, output, output);
+
+ if (rv != 0) {
+ if (output.Length > 0)
+ Console.WriteLine (output);
+ }
+
+ ParseMessages ();
+
+ return rv;
+ }
+
+ void ParseMessages ()
+ {
+ messages.Clear ();
+
+ foreach (var l in output.ToString ().Split ('\n')) {
+ var line = l;
+ var msg = new ToolMessage ();
+ if (line.StartsWith ("error ", StringComparison.Ordinal)) {
+ msg.IsError = true;
+ line = line.Substring (6);
+ } else if (line.StartsWith ("warning ", StringComparison.Ordinal)) {
+ msg.IsError = false;
+ line = line.Substring (8);
+ } else {
+ // something else
+ continue;
+ }
+ if (line.Length < 7)
+ continue; // something else
+ msg.Prefix = line.Substring (0, 2);
+ if (!int.TryParse (line.Substring (2, 4), out msg.Number))
+ continue; // something else
+ msg.Message = line.Substring (8);
+
+ messages.Add (msg);
+ }
+ }
+
+ public bool HasErrorPattern (string prefix, int number, string messagePattern)
+ {
+ foreach (var msg in messages) {
+ if (msg.IsError && msg.Prefix == prefix && msg.Number == number && Regex.IsMatch (msg.Message, messagePattern))
+ return true;
+ }
+ return false;
+ }
+
+ public bool HasError (string prefix, int number, string message)
+ {
+ foreach (var msg in messages) {
+ if (msg.IsError && msg.Prefix == prefix && msg.Number == number && msg.Message == message)
+ return true;
+ }
+ return false;
+ }
+
+ public void AssertErrorPattern (int number, string messagePattern)
+ {
+ AssertErrorPattern ("MT", number, messagePattern);
+ }
+
+ public void AssertErrorPattern (string prefix, int number, string messagePattern)
+ {
+ if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number))
+ Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number));
+
+ if (messages.Any ((msg) => Regex.IsMatch (msg.Message, messagePattern)))
+ return;
+
+ var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && !Regex.IsMatch (msg.Message, messagePattern)).Select ((msg) => string.Format ("\tThe message '{0}' did not match the pattern '{1}'.", msg.Message, messagePattern));
+ Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, messagePattern, string.Join ("\n", details.ToArray ())));
+ }
+
+ public void AssertError (int number, string message)
+ {
+ AssertError ("MT", number, message);
+ }
+
+ public void AssertError (string prefix, int number, string message)
+ {
+ if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number))
+ Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number));
+
+ if (messages.Any ((msg) => msg.Message == message))
+ return;
+
+ var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message).Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1));
+ Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ())));
+ }
+
+ public bool HasOutput (string line)
+ {
+ return OutputLines.Contains (line);
+ }
+
+ public bool HasOutputPattern (string linePattern)
+ {
+ foreach (var line in OutputLines) {
+ if (Regex.IsMatch (line, linePattern, RegexOptions.CultureInvariant))
+ return true;
+ }
+
+ return false;
+ }
+
+ public void AssertOutputPattern (string linePattern)
+ {
+ if (!HasOutputPattern (linePattern))
+ Assert.Fail (string.Format ("The output does not contain the line '{0}'", linePattern));
+ }
+ }
+
+ class XBuild
+ {
+ public static string ToolPath {
+ get
+ {
+ return "/Library/Frameworks/Mono.framework/Commands/xbuild";
+ }
+ }
+
+ public static void Build (string project, string configuration = "Debug", string platform = "iPhoneSimulator", string verbosity = null)
+ {
+ ExecutionHelper.Execute (ToolPath, string.Format ("/p:Configuration={0} /p:Platform={1} {2} \"{3}\"", configuration, platform, verbosity == null ? string.Empty : "/verbosity:" + verbosity, project));
+ }
+ }
+
+ static class ExecutionHelper {
+ static int Execute (ProcessStartInfo psi, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null)
+ {
+ var watch = new Stopwatch ();
+ watch.Start ();
+
+ try {
+ psi.UseShellExecute = false;
+ psi.RedirectStandardError = true;
+ psi.RedirectStandardOutput = true;
+ Console.WriteLine ("{0} {1}", psi.FileName, psi.Arguments);
+ using (var p = new Process ()) {
+ p.StartInfo = psi;
+ // mtouch/mmp writes UTF8 data outside of the ASCII range, so we need to make sure
+ // we read it in the same format. This also means we can't use the events to get
+ // stdout/stderr, because mono's Process class parses those using Encoding.Default.
+ p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
+ p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
+ p.Start ();
+
+ var outReader = new Thread (() =>
+ {
+ string l;
+ while ((l = p.StandardOutput.ReadLine ()) != null) {
+ lock (stdout)
+ stdout.AppendLine (l);
+ }
+ })
+ {
+ IsBackground = true,
+ };
+ outReader.Start ();
+
+ var errReader = new Thread (() =>
+ {
+ string l;
+ while ((l = p.StandardError.ReadLine ()) != null) {
+ lock (stderr)
+ stderr.AppendLine (l);
+ }
+ })
+ {
+ IsBackground = true,
+ };
+ errReader.Start ();
+
+ if (timeout == null)
+ timeout = TimeSpan.FromMinutes (5);
+ if (!p.WaitForExit ((int) timeout.Value.TotalMilliseconds)) {
+ Console.WriteLine ("Command didn't finish in {0} minutes:", timeout.Value.TotalMinutes);
+ Console.WriteLine ("{0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments);
+ Console.WriteLine ("Will now kill the process");
+ kill (p.Id, 9);
+ if (!p.WaitForExit (1000 /* killing should be fairly quick */)) {
+ Console.WriteLine ("Kill failed to kill in 1 second !?");
+ return 1;
+ }
+ }
+
+ outReader.Join (TimeSpan.FromSeconds (1));
+ errReader.Join (TimeSpan.FromSeconds (1));
+
+ return p.ExitCode;
+ }
+ } finally {
+ Console.WriteLine ("{0} Executed in {1}: {2} {3}", DateTime.Now, watch.Elapsed.ToString (), psi.FileName, psi.Arguments);
+ }
+ }
+
+ public static int Execute (string fileName, string arguments, out string output, TimeSpan? timeout = null)
+ {
+ var sb = new StringBuilder ();
+ var psi = new ProcessStartInfo ();
+ psi.FileName = fileName;
+ psi.Arguments = arguments;
+ var rv = Execute (psi, sb, sb, timeout);
+ output = sb.ToString ();
+ return rv;
+ }
+
+ public static int Execute (string fileName, string arguments, Dictionary environmentVariables, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null)
+ {
+ if (stdout == null)
+ stdout = new StringBuilder ();
+ if (stderr == null)
+ stderr = new StringBuilder ();
+
+ var psi = new ProcessStartInfo ();
+ psi.FileName = fileName;
+ psi.Arguments = arguments;
+ if (environmentVariables != null) {
+ var envs = psi.EnvironmentVariables;
+ foreach (var kvp in environmentVariables) {
+ if (envs.ContainsKey (kvp.Key))
+ envs [kvp.Key] += ":" + kvp.Value;
+ else
+ envs.Add (kvp.Key, kvp.Value);
+ }
+ }
+
+ return Execute (psi, stdout, stderr, timeout);
+ }
+
+ [DllImport ("libc")]
+ private static extern void kill (int pid, int sig);
+
+ public static string Execute (string fileName, string arguments, bool throwOnError = true, Dictionary environmentVariables = null,
+ bool hide_output = false
+ )
+ {
+ StringBuilder output = new StringBuilder ();
+ int exitCode = Execute (fileName, arguments, environmentVariables, output, output);
+ if (!hide_output) {
+ Console.WriteLine ("{0} {1}", fileName, arguments);
+ Console.WriteLine (output);
+ }
+ if (throwOnError && exitCode != 0)
+ throw new TestExecutionException (output.ToString ());
+ return output.ToString ();
+ }
+ }
+
+ class TestExecutionException : Exception {
+ public TestExecutionException (string output)
+ : base (output)
+ {
+ }
+ }
+}
diff --git a/tests/common/mac/ApiDefinition.cs b/tests/common/mac/ApiDefinition.cs
new file mode 100644
index 000000000000..049583b57371
--- /dev/null
+++ b/tests/common/mac/ApiDefinition.cs
@@ -0,0 +1,68 @@
+using System;
+
+using AppKit;
+using Foundation;
+using ObjCRuntime;
+using CoreGraphics;
+
+namespace ExampleBinding
+{
+ // The first step to creating a binding is to add your native library ("libNativeLibrary.a")
+ // to the project by right-clicking (or Control-clicking) the folder containing this source
+ // file and clicking "Add files..." and then simply select the native library (or libraries)
+ // that you want to bind.
+ //
+ // When you do that, you'll notice that MonoDevelop generates a code-behind file for each
+ // native library which will contain a [LinkWith] attribute. MonoDevelop auto-detects the
+ // architectures that the native library supports and fills in that information for you,
+ // however, it cannot auto-detect any Frameworks or other system libraries that the
+ // native library may depend on, so you'll need to fill in that information yourself.
+ //
+ // Once you've done that, you're ready to move on to binding the API...
+ //
+ //
+ // Here is where you'd define your API definition for the native Objective-C library.
+ //
+ // For example, to bind the following Objective-C class:
+ //
+ // @interface Widget : NSObject {
+ // }
+ //
+ // The C# binding would look like this:
+ //
+ // [BaseType (typeof (NSObject))]
+ // interface Widget {
+ // }
+ //
+ // To bind Objective-C properties, such as:
+ //
+ // @property (nonatomic, readwrite, assign) CGPoint center;
+ //
+ // You would add a property definition in the C# interface like so:
+ //
+ // [Export ("center")]
+ // CGPoint Center { get; set; }
+ //
+ // To bind an Objective-C method, such as:
+ //
+ // -(void) doSomething:(NSObject *)object atIndex:(NSInteger)index;
+ //
+ // You would add a method definition to the C# interface like so:
+ //
+ // [Export ("doSomething:atIndex:")]
+ // void DoSomething (NSObject object, int index);
+ //
+ // Objective-C "constructors" such as:
+ //
+ // -(id)initWithElmo:(ElmoMuppet *)elmo;
+ //
+ // Can be bound as:
+ //
+ // [Export ("initWithElmo:")]
+ // IntPtr Constructor (ElmoMuppet elmo);
+ //
+ // For more information, see http://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/
+ //
+%CODE%
+}
+
diff --git a/tests/common/mac/BindingProjectWithNoTag.csproj b/tests/common/mac/BindingProjectWithNoTag.csproj
new file mode 100644
index 000000000000..2b10757338ff
--- /dev/null
+++ b/tests/common/mac/BindingProjectWithNoTag.csproj
@@ -0,0 +1,40 @@
+
+
+
+ Debug
+ AnyCPU
+ {810C163F-4746-4721-8B8E-88A3673A62EA};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {ED1B29DD-8FCB-48D4-A0E1-BE98446C9C53}
+ Library
+ BindingProjectWithNoTag
+ Resources
+ BindingProjectWithNoTag
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+%CODE%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/ClassicExample.csproj b/tests/common/mac/ClassicExample.csproj
new file mode 100644
index 000000000000..3d304c4b3ccc
--- /dev/null
+++ b/tests/common/mac/ClassicExample.csproj
@@ -0,0 +1,49 @@
+
+
+
+ Debug
+ AnyCPU
+ {42C0BBD9-55CE-4FC1-8D90-A7348ABAFB23};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {70E29818-C77A-477D-B394-E9F8B03F2C1B}
+ Exe
+ ClassicExample
+ Resources
+ ClassicExample
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ false
+ false
+ false
+ false
+ Mac Developer
+ false
+ false
+%CODE%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/common/mac/Component1.fs b/tests/common/mac/Component1.fs
new file mode 100644
index 000000000000..36da391d07be
--- /dev/null
+++ b/tests/common/mac/Component1.fs
@@ -0,0 +1,3 @@
+namespace FSharpXM45Library
+type Class1() =
+ member this.X = "F#"
diff --git a/tests/common/mac/FSharpUnifiedExample.fsproj b/tests/common/mac/FSharpUnifiedExample.fsproj
new file mode 100644
index 000000000000..10eb5fb828a1
--- /dev/null
+++ b/tests/common/mac/FSharpUnifiedExample.fsproj
@@ -0,0 +1,48 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{F2A71F9B-5D33-465A-A702-920D77279786}
+ {517BFCB9-A89A-45E4-810A-4BDCBE451CF7}
+ Exe
+ FSharpUnifiedExample
+ Resources
+ FSharpUnifiedExample
+ v2.0
+ Xamarin.Mac
+
+
+ true
+ false
+ bin\Debug
+ DEBUG
+ prompt
+ true
+ true
+ true
+ false
+ false
+ false
+ Mac Developer
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/FSharpUnifiedLibrary.fsproj b/tests/common/mac/FSharpUnifiedLibrary.fsproj
new file mode 100644
index 000000000000..58625d9e4579
--- /dev/null
+++ b/tests/common/mac/FSharpUnifiedLibrary.fsproj
@@ -0,0 +1,50 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{F2A71F9B-5D33-465A-A702-920D77279786}
+ {5318A97A-4738-4BBF-973D-CC6CD93AA973}
+ Library
+ FSharpUnifiedLibrary
+ Resources
+ FSharpUnifiedLibrary
+ v2.0
+ Xamarin.Mac
+
+
+ true
+ false
+ bin\Debug
+ DEBUG
+ prompt
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/FSharpXM45Example.fsproj b/tests/common/mac/FSharpXM45Example.fsproj
new file mode 100644
index 000000000000..515f04c53c4b
--- /dev/null
+++ b/tests/common/mac/FSharpXM45Example.fsproj
@@ -0,0 +1,47 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{F2A71F9B-5D33-465A-A702-920D77279786}
+ {1C0E1136-9F26-4C13-A049-7839D5ABB4FF}
+ Exe
+ FSharpXM45Example
+ Resources
+ FSharpXM45Example
+ true
+
+
+ true
+ false
+ bin\Debug
+ DEBUG
+ prompt
+ true
+ true
+ true
+ false
+ false
+ false
+ Mac Developer
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/FSharpXM45Library.fsproj b/tests/common/mac/FSharpXM45Library.fsproj
new file mode 100644
index 000000000000..fe498972daa9
--- /dev/null
+++ b/tests/common/mac/FSharpXM45Library.fsproj
@@ -0,0 +1,49 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{F2A71F9B-5D33-465A-A702-920D77279786}
+ {3C11EFFC-888C-4D8F-8133-F6B2947EBEE7}
+ Library
+ FSharpXM45Library
+ Resources
+ FSharpXM45Library
+ true
+
+
+ true
+ false
+ bin\Debug
+ DEBUG
+ prompt
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/Finder/Entitlements.plist b/tests/common/mac/Finder/Entitlements.plist
new file mode 100644
index 000000000000..ffef54421f6d
--- /dev/null
+++ b/tests/common/mac/Finder/Entitlements.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
+
diff --git a/tests/common/mac/Finder/FinderExtensionTest.csproj b/tests/common/mac/Finder/FinderExtensionTest.csproj
new file mode 100644
index 000000000000..8e5fcb31ae03
--- /dev/null
+++ b/tests/common/mac/Finder/FinderExtensionTest.csproj
@@ -0,0 +1,64 @@
+
+
+
+ Debug
+ AnyCPU
+ {B20EB7A2-A5ED-4CB9-95B3-58209092BF69}
+ {889C2465-30A1-4310-B175-96B1F4D843DE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ FinderExtensionTest
+ FinderExtensionTest
+ v2.0
+ Xamarin.Mac
+ Resources
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ false
+ Mac Developer
+ false
+ false
+ false
+ true
+ true
+ true
+
+
+ true
+ bin\Release
+ prompt
+ 4
+ false
+ true
+ Developer ID Application
+ true
+ false
+ true
+ true
+ true
+ SdkOnly
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/common/mac/Finder/FinderSync.cs b/tests/common/mac/Finder/FinderSync.cs
new file mode 100644
index 000000000000..b9fdb6c71377
--- /dev/null
+++ b/tests/common/mac/Finder/FinderSync.cs
@@ -0,0 +1,51 @@
+using AppKit;
+using FinderSync;
+using Foundation;
+using Social;
+
+namespace FinderExtensionTest
+{
+ [Register ("FinderSync")]
+ public partial class FinderSync : FIFinderSync
+ {
+ public override void BeginRequestWithExtensionContext (NSExtensionContext context)
+ {
+ }
+
+ public override NSMenu GetMenu (FIMenuKind menuKind)
+ {
+ NSMenu menu = new NSMenu ("");
+ menu.AddItem ("Menu Item from C#", new ObjCRuntime.Selector ("sampleAction:"), "");
+ return menu;
+ }
+
+ public override string ToolbarItemName
+ {
+ get
+ {
+ return "FinderExtension";
+ }
+ }
+
+ public override string ToolbarItemToolTip
+ {
+ get
+ {
+ return "FinderExtension: Click the toolbar item for a menu.";
+ }
+ }
+
+ public override NSImage ToolbarItemImage
+ {
+ get
+ {
+ return NSImage.ImageNamed (NSImageName.Caution);
+ }
+ }
+
+ [Export ("sampleAction:")]
+ public void Action (NSObject sender)
+ {
+ }
+ }
+}
diff --git a/tests/common/mac/Finder/Info.plist b/tests/common/mac/Finder/Info.plist
new file mode 100644
index 000000000000..f8dba6737849
--- /dev/null
+++ b/tests/common/mac/Finder/Info.plist
@@ -0,0 +1,42 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ FinderSyncExtension
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ com.your-company.FinderExtensionTest
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ XPC!
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.10
+ LSUIElement
+
+ NSExtension
+
+ NSExtensionAttributes
+
+ NSExtensionPointIdentifier
+ com.apple.FinderSync
+ NSExtensionPrincipalClass
+ FinderSync
+
+ NSPrincipalClass
+ NSApplication
+
+
+
diff --git a/tests/common/mac/Info-Classic.plist b/tests/common/mac/Info-Classic.plist
new file mode 100644
index 000000000000..0e6cda3d6dd0
--- /dev/null
+++ b/tests/common/mac/Info-Classic.plist
@@ -0,0 +1,21 @@
+
+
+
+
+ CFBundleDisplayName
+ ClassicExample
+ CFBundleIdentifier
+ com.your-company.ClassicExample
+ CFBundleName
+ ClassicExample
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.7
+ NSMainNibFile
+ MainMenu
+ NSPrincipalClass
+ NSApplication
+
+
+
diff --git a/tests/common/mac/Info-Unified.plist b/tests/common/mac/Info-Unified.plist
new file mode 100644
index 000000000000..265bfd98045b
--- /dev/null
+++ b/tests/common/mac/Info-Unified.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDisplayName
+ UnifiedExample
+ CFBundleDevelopmentRegion
+ en
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ com.your-company.UnifiedExample
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ UnifiedExample
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.7
+ NSHumanReadableCopyright
+ donblas
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/tests/common/mac/MacTestMain.cs b/tests/common/mac/MacTestMain.cs
index ac20b4908c97..c141ae33b6e9 100644
--- a/tests/common/mac/MacTestMain.cs
+++ b/tests/common/mac/MacTestMain.cs
@@ -32,22 +32,22 @@ static void RunTests()
class NSRunLoopIntegration : NSObject, IMainLoopIntegration
{
- public void InitializeToolkit ()
+ public void InitializeToolkit()
{
}
- public void RunMainLoop ()
+ public void RunMainLoop()
{
}
-
- public void InvokeOnMainLoop (InvokerHelper helper)
+
+ public void InvokeOnMainLoop(InvokerHelper helper)
{
- NSApplication.SharedApplication.InvokeOnMainThread (helper.Invoke);
+ NSApplication.SharedApplication.InvokeOnMainThread(helper.Invoke);
}
- public void Shutdown ()
+ public void Shutdown()
{
- Environment.Exit (TestRunner.ExitCode);
+ Environment.Exit(TestRunner.ExitCode);
}
}
}
diff --git a/tests/common/mac/MobileBinding.csproj b/tests/common/mac/MobileBinding.csproj
new file mode 100644
index 000000000000..b5f8fe145e34
--- /dev/null
+++ b/tests/common/mac/MobileBinding.csproj
@@ -0,0 +1,42 @@
+
+
+
+ Debug
+ AnyCPU
+ {810C163F-4746-4721-8B8E-88A3673A62EA};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {63E49BF0-83BB-450C-8079-8D7437C2C157}
+ Library
+ MobileBinding
+ Resources
+ MobileBinding
+ v2.0
+ Xamarin.Mac
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+%CODE%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/MyClass.cs b/tests/common/mac/MyClass.cs
new file mode 100644
index 000000000000..ef728deed5a9
--- /dev/null
+++ b/tests/common/mac/MyClass.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Library
+{
+ public class MyClass
+ {
+ public MyClass ()
+ {
+ }
+ }
+}
+
diff --git a/tests/common/mac/ProjectTestHelpers.cs b/tests/common/mac/ProjectTestHelpers.cs
new file mode 100644
index 000000000000..5cf7a99145b0
--- /dev/null
+++ b/tests/common/mac/ProjectTestHelpers.cs
@@ -0,0 +1,449 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using NUnit.Framework;
+using System.Reflection;
+
+namespace Xamarin.MMP.Tests
+{
+ // Hide the hacks and provide a nice interface for writting tests that build / run XM projects
+ static class TI
+ {
+ public class UnifiedTestConfig
+ {
+ public string TmpDir { get; set; }
+
+ // Not necessarly required
+ public bool FSharp { get; set; }
+ public bool XM45 { get; set; }
+ public string ProjectName { get; set; }
+ public string TestCode { get; set; }
+ public string CSProjConfig { get; set; }
+ public string References { get; set; }
+ public string AssemblyName { get; set; }
+ public string ItemGroup { get; set; }
+ public string SystemMonoVersion { get; set; }
+
+ // Binding project specific
+ public string APIDefinitionConfig { get; set; }
+ public string StructsAndEnumsConfig { get; set; }
+
+ public UnifiedTestConfig (string tmpDir)
+ {
+ TmpDir = tmpDir;
+ ProjectName = "";
+ TestCode = "";
+ CSProjConfig = "";
+ References = "";
+ AssemblyName = "";
+ APIDefinitionConfig = "";
+ StructsAndEnumsConfig = "";
+ ItemGroup = "";
+ SystemMonoVersion = "";
+ }
+ }
+
+ public static string AssemblyDirectory
+ {
+ get
+ {
+ string codeBase = Assembly.GetExecutingAssembly ().CodeBase;
+ UriBuilder uri = new UriBuilder (codeBase);
+ string path = Uri.UnescapeDataString (uri.Path);
+ return Path.GetDirectoryName (path);
+ }
+ }
+
+ public static Version FindMonoVersion ()
+ {
+ string output = RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/mono", new StringBuilder ("--version"), "FindMonoVersion");
+
+ Regex versionRegex = new Regex("compiler version \\d.\\d.\\d", RegexOptions.IgnoreCase);
+ return new Version (versionRegex.Match (output).Value.Split (' ')[2]);
+ }
+
+ public static string RunAndAssert (string exe, StringBuilder args, string stepName, bool shouldFail = false, Func getAdditionalFailInfo = null)
+ {
+ StringBuilder output = new StringBuilder ();
+ Environment.SetEnvironmentVariable ("MONO_PATH", null);
+ int compileResult = Xamarin.Bundler.Driver.RunCommand (exe, args != null ? args.ToString() : string.Empty, MonoDevelopLike, output, suppressPrintOnErrors: shouldFail);
+ Func getInfo = () => getAdditionalFailInfo != null ? getAdditionalFailInfo() : "";
+ if (!shouldFail)
+ Assert.AreEqual (0, compileResult, stepName + " failed: '" + output + "' " + exe + " " + args + getInfo ());
+ else
+ Assert.AreNotEqual (0, compileResult, stepName + " did not fail as expected: '" + output + "' " + exe + " " + args + getInfo ());
+
+ return output.ToString ();
+ }
+
+ public static string BuildProject (string csprojTarget, bool isUnified, bool shouldFail = false)
+ {
+ string rootDirectory = FindRootDirectory ();
+
+ // These are required to have xbuild use are local build instead of system install
+ Environment.SetEnvironmentVariable ("XBUILD_FRAMEWORK_FOLDERS_PATH", rootDirectory + "/Library/Frameworks/Mono.framework/External/xbuild-frameworks");
+ Environment.SetEnvironmentVariable ("MSBuildExtensionsPath", rootDirectory + "/Library/Frameworks/Mono.framework/External/xbuild");
+ Environment.SetEnvironmentVariable ("XAMMAC_FRAMEWORK_PATH", rootDirectory + "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current");
+
+ // This is to force build to use our mmp and not system mmp
+ StringBuilder buildArgs = new StringBuilder ();
+ if (isUnified) {
+ buildArgs.Append (" /verbosity:normal ");
+ buildArgs.Append (" /property:XamarinMacFrameworkRoot=" + rootDirectory + "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current ");
+ } else
+ buildArgs.Append (" build ");
+
+ buildArgs.Append (csprojTarget);
+
+
+ if (isUnified)
+ return RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/xbuild", buildArgs, "Compile", shouldFail, () => File.ReadAllText (csprojTarget));
+ else
+ return RunAndAssert ("/Applications/Xamarin Studio.app/Contents/MacOS/mdtool", buildArgs, "Compile", shouldFail, () => File.ReadAllText (csprojTarget));
+ }
+
+ static string ProjectTextReplacement (UnifiedTestConfig config, string text)
+ {
+ return text.Replace ("%CODE%", config.CSProjConfig).Replace ("%REFERENCES%", config.References).Replace ("%NAME%", config.AssemblyName ?? Path.GetFileNameWithoutExtension (config.ProjectName)).Replace ("%ITEMGROUP%", config.ItemGroup);
+ }
+
+ static void RunEXEAndVerifyGUID (string tmpDir, Guid guid, string path)
+ {
+ // Assert that the program actually runs and returns our guid
+ Assert.IsTrue (File.Exists (path), string.Format ("{0} did not generate an exe?", path));
+ string output = RunAndAssert (path, null, "Run");
+ Assert.IsTrue(File.Exists (Path.Combine (tmpDir, guid.ToString ())), "Generated program did not create expected guid file: " + output);
+ }
+
+ public static string GenerateEXEProject (UnifiedTestConfig config)
+ {
+ WriteMainFile (config.TestCode, true, config.FSharp, Path.Combine (config.TmpDir, config.FSharp ? "Main.fs" : "Main.cs"));
+
+ string sourceDir = FindSourceDirectory ();
+ File.Copy (Path.Combine (sourceDir, "Info-Unified.plist"), Path.Combine (config.TmpDir, "Info.plist"), true);
+
+ return CopyFileWithSubstitutions (Path.Combine (sourceDir, config.ProjectName), Path.Combine (config.TmpDir, config.ProjectName), text =>
+ {
+ return ProjectTextReplacement (config, text);
+ });
+ }
+
+ public static string GenerateBindingLibraryProject (UnifiedTestConfig config)
+ {
+ string sourceDir = FindSourceDirectory ();
+ CopyFileWithSubstitutions (Path.Combine (sourceDir, "ApiDefinition.cs"), Path.Combine (config.TmpDir, "ApiDefinition.cs"), text => text.Replace ("%CODE%", config.APIDefinitionConfig));
+ CopyFileWithSubstitutions (Path.Combine (sourceDir, "StructsAndEnums.cs"), Path.Combine (config.TmpDir, "StructsAndEnums.cs"), text => text.Replace ("%CODE%", config.StructsAndEnumsConfig));
+
+ return CopyFileWithSubstitutions (Path.Combine (sourceDir, config.ProjectName), Path.Combine (config.TmpDir, config.ProjectName), text => {
+ return ProjectTextReplacement (config, text);
+ });
+ }
+
+ public static string GenerateUnifiedLibraryProject (UnifiedTestConfig config)
+ {
+ string sourceDir = FindSourceDirectory ();
+ string sourceFileName = config.FSharp ? "Component1.fs" : "MyClass.cs";
+ string projectSuffix = config.FSharp ? ".fsproj" : ".csproj";
+ File.Copy (Path.Combine (sourceDir, sourceFileName), Path.Combine (config.TmpDir, sourceFileName), true);
+
+ return CopyFileWithSubstitutions (Path.Combine (sourceDir, config.ProjectName + projectSuffix), Path.Combine (config.TmpDir, config.ProjectName + projectSuffix), text => {
+ return ProjectTextReplacement (config, text);
+ });
+ }
+
+ public static string BuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false)
+ {
+ string projectName;
+ if (config.FSharp)
+ projectName = config.XM45 ? "FSharpXM45Example" : "FSharpUnifiedExample";
+ else
+ projectName = config.XM45 ? "XM45Example" : "UnifiedExample";
+ string projectExtension = config.FSharp ? ".fsproj" : ".csproj";
+
+ config.ProjectName = projectName + projectExtension;
+ string csprojTarget = GenerateEXEProject (config);
+
+ return BuildProject (csprojTarget, isUnified: true, shouldFail: shouldFail);
+ }
+
+ public static string TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false)
+ {
+ string projectName;
+ if (config.FSharp)
+ projectName = config.XM45 ? "FSharpXM45Example" : "FSharpUnifiedExample";
+ else
+ projectName = config.XM45 ? "XM45Example" : "UnifiedExample";
+ string projectExtension = config.FSharp ? ".fsproj" : ".csproj";
+
+ Guid guid = Guid.NewGuid ();
+ config.TestCode += GenerateOuputCommand (config.TmpDir, guid);
+ config.ProjectName = projectName + projectExtension;
+ string csprojTarget = GenerateEXEProject (config);
+
+ string buildOutput = BuildProject (csprojTarget, isUnified : true, shouldFail : shouldFail);
+ if (shouldFail)
+ return buildOutput;
+
+ string bundleName = config.AssemblyName != "" ? config.AssemblyName : projectName;
+ string exePath = Path.Combine (config.TmpDir, "bin/Debug/" + bundleName + ".app/Contents/MacOS/" + bundleName);
+ RunEXEAndVerifyGUID (config.TmpDir, guid, exePath);
+ return buildOutput;
+ }
+
+ public static string TestClassicExecutable (string tmpDir, string testCode = "", string csprojConfig = "", bool shouldFail = false)
+ {
+ Guid guid = Guid.NewGuid ();
+ string csprojTarget = GenerateClassicEXEProject (tmpDir, "ClassicExample.csproj", testCode + GenerateOuputCommand (tmpDir,guid), csprojConfig, "");
+ string buildOutput = BuildProject (csprojTarget, isUnified : false, shouldFail : shouldFail);
+ if (shouldFail)
+ return buildOutput;
+
+ string exePath = Path.Combine (tmpDir, "bin/Debug/ClassicExample.app/Contents/MacOS/ClassicExample");
+ RunEXEAndVerifyGUID (tmpDir, guid, exePath);
+ return buildOutput;
+ }
+
+ public static string TestSystemMonoExecutable (UnifiedTestConfig config, bool shouldFail = false)
+ {
+ Guid guid = Guid.NewGuid ();
+ var projectName = "SystemMonoExample";
+ config.TestCode += GenerateOuputCommand (config.TmpDir, guid);
+ config.ProjectName = $"{projectName}.csproj";
+ string csprojTarget = GenerateSystemMonoEXEProject (config);
+
+ string buildOutput = BuildProject (csprojTarget, isUnified : true, shouldFail : shouldFail);
+ if (shouldFail)
+ return buildOutput;
+
+ string exePath = Path.Combine (config.TmpDir, "bin/Debug/" + projectName + ".app/Contents/MacOS/" + projectName);
+ RunEXEAndVerifyGUID (config.TmpDir, guid, exePath);
+ return buildOutput;
+ }
+
+ public static string GenerateClassicEXEProject (string tmpDir, string projectName, string testCode, string csprojConfig = "", string references = "", string assemblyName = null)
+ {
+ WriteMainFile (testCode, false, false, Path.Combine (tmpDir, "Main.cs"));
+
+ string sourceDir = FindSourceDirectory ();
+ File.Copy (Path.Combine (sourceDir, "Info-Classic.plist"), Path.Combine (tmpDir, "Info.plist"), true);
+
+ return CopyFileWithSubstitutions (Path.Combine (sourceDir, projectName), Path.Combine (tmpDir, projectName), text =>
+ {
+ return text.Replace ("%CODE%", csprojConfig).Replace ("%REFERENCES%", references).Replace ("%NAME%", assemblyName ?? Path.GetFileNameWithoutExtension (projectName));
+ });
+ }
+
+ static string GetTargetFrameworkValue (UnifiedTestConfig config)
+ {
+ string version = config.SystemMonoVersion == "" ? "4.5" : config.SystemMonoVersion;
+ return string.Format ("v{0}", version);
+ }
+
+ public static string GenerateSystemMonoEXEProject (UnifiedTestConfig config)
+ {
+ WriteMainFile (config.TestCode, true, false, Path.Combine (config.TmpDir, "Main.cs"));
+
+ string sourceDir = FindSourceDirectory ();
+ File.Copy (Path.Combine (sourceDir, "Info-Unified.plist"), Path.Combine (config.TmpDir, "Info.plist"), true);
+
+ return CopyFileWithSubstitutions (Path.Combine (sourceDir, config.ProjectName), Path.Combine (config.TmpDir, config.ProjectName), text =>
+ {
+ return ProjectTextReplacement (config, text.Replace ("%TARGETFRAMEWORKVERSION%", GetTargetFrameworkValue (config)));
+ });
+ }
+
+ public static string TestDirectory => "../../../../../../../";
+
+ public static string FindSourceDirectory ()
+ {
+ string codeBase = System.Reflection.Assembly.GetExecutingAssembly ().CodeBase;
+ UriBuilder uri = new UriBuilder (codeBase);
+ string path = Uri.UnescapeDataString (uri.Path);
+ string assemblyDirectory = Path.GetDirectoryName (path);
+ return Path.Combine(assemblyDirectory, TestDirectory + "common/mac");
+ }
+
+ static string CopyFileWithSubstitutions (string src, string target, Func replacementAction)
+ {
+ string text = replacementAction (System.IO.File.ReadAllText (src));
+ System.IO.File.WriteAllText (target, text);
+ return target;
+ }
+
+ // Configuration.MonoDevelopLike is a Dictionary but RunCommand wants string [], convert!
+ static string [] MonoDevelopLike {
+ get {
+ List keys = Xamarin.Tests.Configuration.MonoDevelopLike.Keys.ToList ();
+ int numberOfKeys = keys.Count ();
+ var retValue = new string [numberOfKeys * 2 + 2];
+ for (int i = 0 ; i < numberOfKeys ; i++) {
+ retValue[i * 2] = keys[i];
+ if (keys[i] == "PATH") // For some reason MonoDevelopLike is blapping PATH so we can't find xcrun
+ retValue[1 + (i * 2)] = Xamarin.Tests.Configuration.MonoDevelopLike[keys[i]] + ":/usr/bin";
+ else
+ retValue[1 + (i * 2)] = Xamarin.Tests.Configuration.MonoDevelopLike[keys[i]];
+ }
+ retValue [numberOfKeys * 2] = "MD_APPLE_SDK_ROOT";
+ retValue [numberOfKeys * 2 + 1] = System.Environment.GetEnvironmentVariable ("MD_APPLE_SDK_ROOT");
+ return retValue;
+ }
+ }
+
+ static void WriteMainFile (string content, bool isUnified, bool fsharp, string location)
+ {
+ const string FSharpMainTemplate = @"
+namespace FSharpUnifiedExample
+open System
+open AppKit
+
+module main =
+ []
+ let main args =
+ NSApplication.Init ()
+ %CODE%
+ 0";
+
+ const string MainTemplate = @"
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+
+namespace TestCase
+{
+ class MainClass
+ {
+ static void Main (string[] args)
+ {
+ NSApplication.Init ();
+ %CODE%
+ }
+ }
+}";
+ string currentTemplate = fsharp ? FSharpMainTemplate : MainTemplate;
+ string testCase = currentTemplate.Replace("%CODE%", content);
+ if (isUnified)
+ testCase = testCase.Replace ("MonoMac.", string.Empty);
+ using (StreamWriter s = new StreamWriter (location))
+ s.Write(testCase);
+ }
+
+ public static string FindRootDirectory ()
+ {
+ var current = Environment.CurrentDirectory;
+ while (!Directory.Exists (Path.Combine (current, "xamarin-macios", "_mac-build")) && current.Length > 1)
+ current = Path.GetDirectoryName (current);
+ if (current.Length <= 1)
+ throw new DirectoryNotFoundException (string.Format ("Could not find the root directory starting from {0}", Environment.CurrentDirectory));
+ return Path.GetFullPath (Path.Combine (current, "xamarin-macios", "_mac-build"));
+ }
+
+ static string GenerateOuputCommand (string tmpDir, Guid guid)
+ {
+ return string.Format ("System.IO.File.Create(\"{0}\").Dispose();", Path.Combine (tmpDir, guid.ToString ()));
+ }
+ }
+
+ static class PlatformHelpers
+ {
+ // Yes, this is a copy of the one in PlatformAvailability.cs. However, right now
+ // we don't depend on Xamarin.Mac.dll, so moving to it was too painful. If we start
+ // using XM, we can revisit.
+ const int sys1 = 1937339185;
+ const int sys2 = 1937339186;
+
+ // Deprecated in OSX 10.8 - but no good alternative is (yet) available
+ [System.Runtime.InteropServices.DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
+ static extern int Gestalt (int selector, out int result);
+
+ static int osx_major, osx_minor;
+
+ public static bool CheckSystemVersion (int major, int minor)
+ {
+ if (osx_major == 0) {
+ Gestalt (sys1, out osx_major);
+ Gestalt (sys2, out osx_minor);
+ }
+ return osx_major > major || (osx_major == major && osx_minor >= minor);
+ }
+ }
+}
+
+// A bit of a hack so we can reuse all of the RunCommand logic
+namespace Xamarin.Bundler {
+ public static partial class Driver
+ {
+ public static int verbose { get { return 0; } }
+ public static int RunCommand (string path, string args, string[] env = null, StringBuilder output = null, bool suppressPrintOnErrors = false)
+ {
+ Exception stdin_exc = null;
+ var info = new ProcessStartInfo (path, args);
+ info.UseShellExecute = false;
+ info.RedirectStandardInput = false;
+ info.RedirectStandardOutput = true;
+ info.RedirectStandardError = true;
+ System.Threading.ManualResetEvent stdout_completed = new System.Threading.ManualResetEvent (false);
+ System.Threading.ManualResetEvent stderr_completed = new System.Threading.ManualResetEvent (false);
+
+ if (output == null)
+ output = new StringBuilder ();
+
+ if (env != null){
+ if (env.Length % 2 != 0)
+ throw new Exception ("You passed an environment key without a value");
+
+ for (int i = 0; i < env.Length; i+= 2)
+ info.EnvironmentVariables [env[i]] = env[i+1];
+ }
+
+ if (verbose > 0)
+ Console.WriteLine ("{0} {1}", path, args);
+
+ using (var p = Process.Start (info)) {
+
+ p.OutputDataReceived += (s, e) => {
+ if (e.Data != null) {
+ lock (output)
+ output.AppendLine (e.Data);
+ } else {
+ stdout_completed.Set ();
+ }
+ };
+
+ p.ErrorDataReceived += (s, e) => {
+ if (e.Data != null) {
+ lock (output)
+ output.AppendLine (e.Data);
+ } else {
+ stderr_completed.Set ();
+ }
+ };
+
+ p.BeginOutputReadLine ();
+ p.BeginErrorReadLine ();
+
+ p.WaitForExit ();
+
+ stderr_completed.WaitOne (TimeSpan.FromSeconds (1));
+ stdout_completed.WaitOne (TimeSpan.FromSeconds (1));
+
+ if (p.ExitCode != 0) {
+ // note: this repeat the failing command line. However we can't avoid this since we're often
+ // running commands in parallel (so the last one printed might not be the one failing)
+ if (!suppressPrintOnErrors)
+ Console.Error.WriteLine ("Process exited with code {0}, command:\n{1} {2}{3}", p.ExitCode, path, args, output.Length > 0 ? "\n" + output.ToString () : string.Empty);
+ return p.ExitCode;
+ } else if (verbose > 0 && output.Length > 0 && !suppressPrintOnErrors) {
+ Console.WriteLine (output.ToString ());
+ }
+
+ if (stdin_exc != null)
+ throw stdin_exc;
+ }
+
+ return 0;
+ }
+ }
+}
diff --git a/tests/common/mac/Share/Entitlements.plist b/tests/common/mac/Share/Entitlements.plist
new file mode 100644
index 000000000000..ffef54421f6d
--- /dev/null
+++ b/tests/common/mac/Share/Entitlements.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
+
diff --git a/tests/common/mac/Share/Info.plist b/tests/common/mac/Share/Info.plist
new file mode 100644
index 000000000000..30862018693f
--- /dev/null
+++ b/tests/common/mac/Share/Info.plist
@@ -0,0 +1,42 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ShareExtension
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ com.your-company.ShareExtensionTest
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ XPC!
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.10
+ NSExtension
+
+ NSExtensionAttributes
+
+ NSExtensionActivationRule
+ TRUEPREDICATE
+
+ NSExtensionPointIdentifier
+ com.apple.share-services
+ NSExtensionPrincipalClass
+ ShareViewController
+
+
+
+
+
diff --git a/tests/common/mac/Share/ShareExtensionTest.csproj b/tests/common/mac/Share/ShareExtensionTest.csproj
new file mode 100644
index 000000000000..59ac3bfe91b1
--- /dev/null
+++ b/tests/common/mac/Share/ShareExtensionTest.csproj
@@ -0,0 +1,70 @@
+
+
+
+ Debug
+ AnyCPU
+ {8D3616B0-B9BC-46E0-A67B-7D0AEA20420C}
+ {889C2465-30A1-4310-B175-96B1F4D843DE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ ShareExtensionTest
+ ShareExtensionTest
+ v2.0
+ Xamarin.Mac
+ Resources
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ false
+ Mac Developer
+ false
+ false
+ false
+ true
+ true
+ true
+
+
+ true
+ bin\Release
+ prompt
+ 4
+ false
+ true
+ Developer ID Application
+ true
+ false
+ true
+ true
+ true
+ SdkOnly
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ShareViewController.cs
+
+
+
+
\ No newline at end of file
diff --git a/tests/common/mac/Share/ShareViewController.cs b/tests/common/mac/Share/ShareViewController.cs
new file mode 100644
index 000000000000..681cb1876b01
--- /dev/null
+++ b/tests/common/mac/Share/ShareViewController.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Drawing;
+
+using NotificationCenter;
+using Foundation;
+using Social;
+using AppKit;
+using System.Linq;
+
+namespace ShareExtensionTest
+{
+ public partial class ShareViewController : NSViewController
+ {
+ public ShareViewController (IntPtr handle) : base (handle)
+ {
+ }
+
+ public override void LoadView ()
+ {
+ base.LoadView ();
+
+ NSExtensionItem item = ExtensionContext.InputItems.First ();
+ Console.WriteLine ("Attachments {0}", item);
+ }
+
+ partial void Cancel (Foundation.NSObject sender)
+ {
+ NSExtensionItem outputItem = new NSExtensionItem ();
+ var outputItems = new[] { outputItem };
+ ExtensionContext.CompleteRequest (outputItems, null);
+ }
+
+ partial void Send (Foundation.NSObject sender)
+ {
+ NSError cancelError = NSError.FromDomain (NSError.CocoaErrorDomain, 3072, null);
+ ExtensionContext.CancelRequest (cancelError);
+ }
+ }
+}
+
diff --git a/tests/common/mac/Share/ShareViewController.designer.cs b/tests/common/mac/Share/ShareViewController.designer.cs
new file mode 100644
index 000000000000..48827d3f5c25
--- /dev/null
+++ b/tests/common/mac/Share/ShareViewController.designer.cs
@@ -0,0 +1,25 @@
+//
+// This file has been generated automatically by MonoDevelop to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+
+using Foundation;
+
+namespace ShareExtensionTest
+{
+ [Register ("ShareViewController")]
+ partial class ShareViewController
+ {
+ [Action ("Cancel:")]
+ partial void Cancel (Foundation.NSObject sender);
+
+ [Action ("Send:")]
+ partial void Send (Foundation.NSObject sender);
+
+ void ReleaseDesignerOutlets ()
+ {
+ }
+ }
+}
+
diff --git a/tests/common/mac/Share/ShareViewController.xib b/tests/common/mac/Share/ShareViewController.xib
new file mode 100644
index 000000000000..592a458e43a2
--- /dev/null
+++ b/tests/common/mac/Share/ShareViewController.xib
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/common/mac/SimpleClass.h b/tests/common/mac/SimpleClass.h
new file mode 100644
index 000000000000..52fcc875e765
--- /dev/null
+++ b/tests/common/mac/SimpleClass.h
@@ -0,0 +1,7 @@
+#import
+
+@interface SimpleClass : NSObject
+
+- (int) doIt;
+
+@end
diff --git a/tests/common/mac/SimpleClass.m b/tests/common/mac/SimpleClass.m
new file mode 100644
index 000000000000..41290ca740a3
--- /dev/null
+++ b/tests/common/mac/SimpleClass.m
@@ -0,0 +1,9 @@
+#import "SimpleClass.h"
+
+@implementation SimpleClass
+
+- (int)doIt {
+ NSLog(@"Hello, World!");
+ return 42;
+}
+@end
diff --git a/tests/common/mac/StructsAndEnums.cs b/tests/common/mac/StructsAndEnums.cs
new file mode 100644
index 000000000000..5f752a96c415
--- /dev/null
+++ b/tests/common/mac/StructsAndEnums.cs
@@ -0,0 +1,6 @@
+using System;
+
+namespace ExampleBinding
+{
+ %CODE%
+}
diff --git a/tests/common/mac/System.Collections.Immutable.dll b/tests/common/mac/System.Collections.Immutable.dll
new file mode 100644
index 000000000000..6fc2d69aad58
Binary files /dev/null and b/tests/common/mac/System.Collections.Immutable.dll differ
diff --git a/tests/common/mac/SystemMonoExample.csproj b/tests/common/mac/SystemMonoExample.csproj
new file mode 100644
index 000000000000..dac1cf3f19eb
--- /dev/null
+++ b/tests/common/mac/SystemMonoExample.csproj
@@ -0,0 +1,44 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {2EEDEBA4-9A84-4CD3-A66F-01379993A637}
+ Exe
+ SystemMonoExample
+ Resources
+ %NAME%
+ 8.0.30703
+ 2.0
+%TARGETFRAMEWORKVERSION%
+
+
+ bin\Debug
+ false
+ false
+ false
+ false
+ false
+ false
+ 4
+ false
+%CODE%
+ falsex86_64Mac DeveloperDeveloper ID Installer
+
+
+
+
+%REFERENCES%
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/common/mac/Today/Entitlements.plist b/tests/common/mac/Today/Entitlements.plist
new file mode 100644
index 000000000000..ffef54421f6d
--- /dev/null
+++ b/tests/common/mac/Today/Entitlements.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
+
diff --git a/tests/common/mac/Today/Info.plist b/tests/common/mac/Today/Info.plist
new file mode 100644
index 000000000000..84103afbbbb9
--- /dev/null
+++ b/tests/common/mac/Today/Info.plist
@@ -0,0 +1,38 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ TodayExtension
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ com.your-company.TodayExtensionTest
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ XPC!
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.10
+ NSExtension
+
+ NSExtensionPointIdentifier
+ com.apple.widget-extension
+ NSExtensionPrincipalClass
+ TodayViewController
+ com.apple.notificationcenter.widget.description
+ TodayExtension
+
+
+
+
diff --git a/tests/common/mac/Today/TodayExtensionTest.csproj b/tests/common/mac/Today/TodayExtensionTest.csproj
new file mode 100644
index 000000000000..e4f99bc96b11
--- /dev/null
+++ b/tests/common/mac/Today/TodayExtensionTest.csproj
@@ -0,0 +1,74 @@
+
+
+
+ Debug
+ AnyCPU
+ {005176FB-37A1-4308-8C2A-07B7ED3E0064}
+ {889C2465-30A1-4310-B175-96B1F4D843DE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ TodayExtensionTest
+ TodayExtensionTest
+ v2.0
+ Xamarin.Mac
+ Resources
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ false
+ Mac Developer
+ false
+ false
+ false
+ true
+ true
+ true
+ Automatic
+ Developer ID Installer
+ Entitlements.plist
+
+
+
+ true
+ bin\Release
+ prompt
+ 4
+ false
+ true
+ Developer ID Application
+ true
+ false
+ true
+ true
+ true
+ SdkOnly
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TodayViewController.cs
+
+
+
+
\ No newline at end of file
diff --git a/tests/common/mac/Today/TodayViewController.cs b/tests/common/mac/Today/TodayViewController.cs
new file mode 100644
index 000000000000..78416c030c0d
--- /dev/null
+++ b/tests/common/mac/Today/TodayViewController.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Drawing;
+
+using NotificationCenter;
+using Foundation;
+using Social;
+using AppKit;
+
+namespace TodayExtensionTest
+{
+ public partial class TodayViewController : NSViewController, INCWidgetProviding
+ {
+ public TodayViewController (IntPtr handle) : base (handle)
+ {
+ }
+
+ public override void ViewDidLoad ()
+ {
+ base.ViewDidLoad ();
+
+ // Do any additional setup after loading the view.
+ }
+
+ [Export ("widgetPerformUpdateWithCompletionHandler:")]
+ public void WidgetPerformUpdate (Action completionHandler)
+ {
+ // Perform any setup necessary in order to update the view.
+
+ // If an error is encoutered, use NCUpdateResultFailed
+ // If there's no update required, use NCUpdateResultNoData
+ // If there's an update, use NCUpdateResultNewData
+
+ completionHandler (NCUpdateResult.NewData);
+ }
+ }
+}
+
diff --git a/tests/common/mac/Today/TodayViewController.designer.cs b/tests/common/mac/Today/TodayViewController.designer.cs
new file mode 100644
index 000000000000..53034c05fcbc
--- /dev/null
+++ b/tests/common/mac/Today/TodayViewController.designer.cs
@@ -0,0 +1,19 @@
+//
+// This file has been generated automatically by MonoDevelop to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+
+using Foundation;
+
+namespace TodayExtensionTest
+{
+ [Register ("TodayViewController")]
+ partial class TodayViewController
+ {
+ void ReleaseDesignerOutlets ()
+ {
+ }
+ }
+}
+
diff --git a/tests/common/mac/Today/TodayViewController.xib b/tests/common/mac/Today/TodayViewController.xib
new file mode 100644
index 000000000000..3add92a71fee
--- /dev/null
+++ b/tests/common/mac/Today/TodayViewController.xib
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/common/mac/UnifiedExample.csproj b/tests/common/mac/UnifiedExample.csproj
new file mode 100644
index 000000000000..077641e43b7a
--- /dev/null
+++ b/tests/common/mac/UnifiedExample.csproj
@@ -0,0 +1,44 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {2EEDEBA4-9A84-4CD3-A66F-01379993A637}
+ Exe
+ UnifiedExample
+ Resources
+ %NAME%
+ v2.0
+ Xamarin.Mac
+
+
+ bin\Debug
+ false
+ false
+ false
+ false
+ false
+ false
+ 4
+ false
+%CODE%
+
+
+
+
+
+%REFERENCES%
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/UnifiedLibrary.csproj b/tests/common/mac/UnifiedLibrary.csproj
new file mode 100644
index 000000000000..288a8ef92706
--- /dev/null
+++ b/tests/common/mac/UnifiedLibrary.csproj
@@ -0,0 +1,47 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {6582F872-AC33-409A-A488-AF78456D94FC}
+ Library
+ UnifiedLibrary
+ Resources
+ %NAME%
+ v2.0
+ Xamarin.Mac
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+%CODE%
+
+
+
+
+
+%REFERENCES%
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/XM45Binding.csproj b/tests/common/mac/XM45Binding.csproj
new file mode 100644
index 000000000000..5e560dca989c
--- /dev/null
+++ b/tests/common/mac/XM45Binding.csproj
@@ -0,0 +1,41 @@
+
+
+
+ Debug
+ AnyCPU
+ {810C163F-4746-4721-8B8E-88A3673A62EA};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {A4B1CA94-3C11-4F47-B4E5-5EB095AFF35E}
+ Library
+ XM45Binding
+ Resources
+ XM45Binding
+ v4.5
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+%CODE%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/XM45Example.csproj b/tests/common/mac/XM45Example.csproj
new file mode 100644
index 000000000000..da6fd450f2af
--- /dev/null
+++ b/tests/common/mac/XM45Example.csproj
@@ -0,0 +1,46 @@
+
+
+
+ Debug
+ AnyCPU
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {2EEDEBA4-9A84-4CD3-A66F-01379993A637}
+ Exe
+ XM45Example
+ Resources
+ %NAME%
+ 8.0.30703
+ 2.0
+ true
+
+
+ bin\Debug
+ false
+ false
+ false
+ false
+ false
+ false
+ 4
+ false
+%CODE%
+ false
+
+
+
+
+
+%REFERENCES%
+
+
+
+
+
+
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/XM45Library.csproj b/tests/common/mac/XM45Library.csproj
new file mode 100644
index 000000000000..b382b1e50b53
--- /dev/null
+++ b/tests/common/mac/XM45Library.csproj
@@ -0,0 +1,32 @@
+
+
+
+ Debug
+ AnyCPU
+ {C668D2F8-68DE-43AC-9F15-0314FF6B73CD}
+ Library
+ XM45Library
+ %NAME%
+ v4.5
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+%CODE%
+
+
+
+%REFERENCES%
+
+
+
+
+
+%ITEMGROUP%
+
diff --git a/tests/common/mac/project_building.mk b/tests/common/mac/project_building.mk
new file mode 100644
index 000000000000..0668a95088b6
--- /dev/null
+++ b/tests/common/mac/project_building.mk
@@ -0,0 +1,35 @@
+SOURCES = $(TEST_SRC) \
+ $(TOP)/tests/common/Configuration.cs \
+ $(TOP)/tests/common/mac/ProjectTestHelpers.cs \
+ $(TOP)/tools/common/Driver.cs \
+ $(TOP)/tools/common/TargetFramework.cs \
+ $(TOP)/src/ObjCRuntime/ErrorHelper.cs \
+ $(TOP)/src/ObjCRuntime/RuntimeException.cs \
+ $(SOURCES_FOR_LICENSE_MGMT)
+
+# Everything that would invalidate a build
+ALL_SOURCE_FILES = $(TEST_SRC) $(SOURCES) $(EXTRA_FILES) Makefile
+
+export MD_APPLE_SDK_ROOT=$(shell dirname `dirname $(XCODE_DEVELOPER_ROOT)`)
+export XBUILD_FRAMEWORK_FOLDERS_PATH=$(MAC_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild-frameworks
+export MSBuildExtensionsPath=$(MAC_DESTDIR)/Library/Frameworks/Mono.framework/External/xbuild
+export XamarinMacFrameworkRoot=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current
+
+ifeq ($(V)$(BUILD_REVISION),)
+NUNIT_VERBOSITY=-nologo -nodots
+else
+NUNIT_VERBOSITY=-labels
+endif
+
+all-local:: $(TESTDLL) $(EXTRA_DEPS)
+
+clean-local::
+ $(Q) rm -fr ./build
+
+run run-test run-tests:: $(TESTDLL) $(EXTRA_DEPS)
+ DEVELOPER_DIR=$(XCODE_DEVELOPER_ROOT) $(MONO_PREFIX)/bin/nunit-console $(TESTDLL) -xml=build/TestResult.xml -noshadow -nothread $(NUNIT_VERBOSITY)
+ $(Q) test -z "$(BUILD_REVISION)" || echo @"MonkeyWrench: AddFile: $(abspath build/TestResult.xml)"
+
+$(TESTDLL): $(ALL_SOURCE_FILES)
+ $(Q) mkdir -p build
+ $(Q) $(SYSTEM_MCS) /debug $(SOURCES) -d:MMP_TEST -d:XAMCORE_2_0 -d:MONOMAC -t:library -r:nunit.framework -out:$(TESTDLL)
diff --git a/tests/dont link/ApiCMAttachmentTest.cs b/tests/dont link/ApiCMAttachmentTest.cs
new file mode 100644
index 000000000000..f9b7450c58aa
--- /dev/null
+++ b/tests/dont link/ApiCMAttachmentTest.cs
@@ -0,0 +1,545 @@
+#if !__WATCHOS__
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Net;
+using System.Linq;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using AudioToolbox;
+using AudioUnit;
+using CoreMedia;
+using CoreFoundation;
+using CoreGraphics;
+using CoreText;
+using CoreServices;
+using CoreVideo;
+using Foundation;
+using ImageIO;
+using MediaToolbox;
+using SystemConfiguration;
+using ObjCRuntime;
+using Security;
+using UIKit;
+#else
+using MonoTouch.AudioToolbox;
+using MonoTouch.AudioUnit;
+using MonoTouch.CoreMedia;
+using MonoTouch.CoreFoundation;
+using MonoTouch.CoreGraphics;
+using MonoTouch.CoreServices;
+using MonoTouch.CoreText;
+using MonoTouch.CoreVideo;
+using MonoTouch.Foundation;
+using MonoTouch.ImageIO;
+using MonoTouch.MediaToolbox;
+using MonoTouch.SystemConfiguration;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Security;
+using MonoTouch.UIKit;
+#endif
+
+#if !__TVOS__
+
+#if XAMCORE_2_0
+using VideoToolbox;
+#else
+using MonoTouch.VideoToolbox;
+#endif
+
+#endif
+
+namespace TouchUnit.Bindings {
+
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class ApiCMAttachmentTest : ApiBaseTest {
+ static Type CMClockType = typeof (CMClock);
+ static Type CMAttachmentInterfaceType = typeof (ICMAttachmentBearer);
+ static Type NativeObjectInterfaceType = typeof (INativeObject);
+ static Type NSObjectType = typeof (NSObject);
+ static Type DispatchSourceType = typeof (DispatchSource);
+ // CN=mail.google.com, O=Google Inc, L=Mountain View, S=California, C=US
+ static public byte[] mail_google_com = {
+ 0x30, 0x82, 0x03, 0x22, 0x30, 0x82, 0x02, 0x8b, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x2b, 0x9f, 0x7e, 0xe5, 0xca, 0x25, 0xa6, 0x25, 0x14,
+ 0x20, 0x47, 0x82, 0x75, 0x3a, 0x9b, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4c,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5a,
+ 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c,
+ 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75,
+ 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29, 0x20,
+ 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x47,
+ 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x30,
+ 0x32, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31,
+ 0x33, 0x30, 0x39, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
+ 0x30, 0x69, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+ 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x14, 0x0d, 0x4d,
+ 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77,
+ 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x0a, 0x47,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x18, 0x30,
+ 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x0f, 0x6d, 0x61, 0x69, 0x6c,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+ 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89,
+ 0x02, 0x81, 0x81, 0x00, 0xaf, 0x39, 0x15, 0x98, 0x68, 0xe4, 0x92, 0xfe,
+ 0x4f, 0x4f, 0xf1, 0xbb, 0xff, 0x0d, 0x2e, 0xb0, 0xfe, 0x25, 0xaa, 0xbd,
+ 0x68, 0x04, 0x67, 0x27, 0xea, 0x6c, 0x43, 0x4c, 0xa7, 0x6d, 0xcb, 0xc8,
+ 0x8f, 0x7e, 0x81, 0xee, 0x87, 0x26, 0x25, 0x10, 0x12, 0x54, 0x33, 0x9e,
+ 0xaa, 0x3d, 0x9b, 0x8f, 0x8e, 0x92, 0xb3, 0x4b, 0x01, 0xe3, 0xf9, 0x4a,
+ 0x29, 0xc3, 0x0f, 0xfd, 0xac, 0xb7, 0xd3, 0x4c, 0x97, 0x29, 0x3f, 0x69,
+ 0x55, 0xcf, 0x70, 0x83, 0x04, 0xaf, 0x2e, 0x04, 0x6e, 0x74, 0xd6, 0x0f,
+ 0x17, 0x09, 0xfe, 0x9e, 0x20, 0x24, 0x24, 0xe3, 0xc7, 0x68, 0x9c, 0xac,
+ 0x11, 0xbd, 0x92, 0xe4, 0xb2, 0x1b, 0x09, 0xf2, 0x02, 0x32, 0xbb, 0x55,
+ 0x1b, 0x2d, 0x16, 0x5f, 0x30, 0x12, 0x23, 0xe2, 0x4c, 0x4a, 0x8d, 0xc2,
+ 0xda, 0x3f, 0xe1, 0xb8, 0xbf, 0xf7, 0x3a, 0xb1, 0x86, 0xbe, 0xf0, 0xc5,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe7, 0x30, 0x81, 0xe4, 0x30,
+ 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+ 0x00, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d,
+ 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
+ 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65,
+ 0x53, 0x47, 0x43, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x28, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+ 0x42, 0x04, 0x01, 0x30, 0x72, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x66, 0x30, 0x64, 0x30, 0x22, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61,
+ 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x32, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77,
+ 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
+ 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65,
+ 0x5f, 0x53, 0x47, 0x43, 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+ 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0x80, 0x11, 0xcd, 0x52, 0x3e,
+ 0x84, 0x29, 0xfb, 0xc1, 0x28, 0xe1, 0x20, 0xe5, 0x02, 0x8f, 0x5f, 0x71,
+ 0x65, 0x58, 0x1d, 0x62, 0x72, 0x57, 0x3c, 0xe6, 0x5e, 0x25, 0x61, 0xd3,
+ 0xcb, 0xad, 0x22, 0xf8, 0xd8, 0x81, 0xa4, 0xe7, 0xf4, 0xae, 0x7c, 0xd9,
+ 0xc1, 0x6d, 0xaa, 0x93, 0x0d, 0x62, 0x07, 0x9f, 0xf2, 0x67, 0x47, 0x99,
+ 0x34, 0x33, 0x4f, 0x3d, 0x02, 0x74, 0xf4, 0x81, 0xd6, 0x38, 0x08, 0x21,
+ 0xe8, 0xe2, 0xa1, 0xfa, 0x05, 0x41, 0x9c, 0x9c, 0xc9, 0xf9, 0xf3, 0xc8,
+ 0xa3, 0xee, 0x0d, 0xa5, 0xd7, 0x50, 0x54, 0x5e, 0x2f, 0x7d, 0x79, 0xb7,
+ 0x7e, 0x0a, 0x7c, 0xb6, 0xe2, 0x2c, 0xa8, 0xae, 0xfe, 0x94, 0xd7, 0xcd,
+ 0x16, 0x30, 0x71, 0x04, 0xaa, 0x9e, 0x79, 0xc3, 0xd2, 0xb6, 0x24, 0xa7,
+ 0x25, 0xab, 0xf0, 0x48, 0x8e, 0x2f, 0xc3, 0xa7, 0xbb, 0x50, 0xdd, 0x0f,
+ 0xcf, 0xb0, };
+
+ // copy-pasted from mono/mcs/class/corlib/Test/System.Security.Cryptography.X509Certificates/X509Cert20Test.cs
+ static public byte[] farscape_pfx = { 0x30, 0x82, 0x06, 0xA3, 0x02, 0x01, 0x03, 0x30, 0x82, 0x06, 0x63, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x06, 0x54, 0x04, 0x82, 0x06, 0x50, 0x30, 0x82, 0x06, 0x4C, 0x30, 0x82, 0x03, 0x8D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x03, 0x7E, 0x04, 0x82, 0x03, 0x7A, 0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x03, 0x72, 0x06, 0x0B, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02, 0xA0, 0x82, 0x02, 0xB6, 0x30, 0x82, 0x02, 0xB2, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30,
+ 0x0E, 0x04, 0x08, 0x67, 0xFE, 0x3A, 0x52, 0x75, 0xF3, 0x82, 0x1F, 0x02, 0x02, 0x07, 0xD0, 0x04, 0x82, 0x02, 0x90, 0x31, 0x6B, 0x00, 0xFA, 0x73, 0xE6, 0x8D, 0x3D, 0x62, 0x93, 0x41, 0xA1, 0x44, 0x04, 0x17, 0x8D, 0x66, 0x7A, 0x75, 0x14, 0x89, 0xA8, 0xD1, 0x4D, 0x2A, 0xD7, 0x20, 0x27, 0x71, 0x58, 0x81, 0x16, 0xB5, 0xA6, 0x41, 0x75, 0x92, 0xB2, 0xF4, 0x0C, 0xAA, 0x9B, 0x00, 0x46, 0x85, 0x85, 0x3B, 0x09, 0x2A, 0x62, 0x33, 0x3F, 0x3D, 0x06, 0xC7, 0xE7, 0x16, 0x0C, 0xA7, 0x1D, 0x9C, 0xDA, 0x9D, 0xD3, 0xC9, 0x05, 0x60, 0xA5, 0xBE, 0xF0, 0x07, 0xD5, 0xA9, 0x4F, 0x8A, 0x80, 0xF8, 0x55, 0x7B, 0x7B, 0x3C,
+ 0xA0, 0x7C, 0x29, 0x29, 0xAB, 0xB1, 0xE1, 0x5A, 0x25, 0xE3, 0x23, 0x6A, 0x56, 0x98, 0x37, 0x68, 0xAF, 0x9C, 0x87, 0xBB, 0x21, 0x6E, 0x68, 0xBE, 0xAE, 0x65, 0x0C, 0x41, 0x8F, 0x5C, 0x3A, 0xB8, 0xB1, 0x9D, 0x42, 0x37, 0xE4, 0xA0, 0x37, 0xA6, 0xB8, 0xAC, 0x85, 0xD7, 0x85, 0x27, 0x68, 0xD0, 0xB6, 0x3D, 0xC7, 0x39, 0x92, 0x41, 0x46, 0x24, 0xDD, 0x08, 0x57, 0x22, 0x6A, 0xC0, 0xB7, 0xAD, 0x52, 0xC6, 0x7F, 0xE5, 0x74, 0x6A, 0x5E, 0x28, 0xA3, 0x85, 0xBD, 0xE8, 0xAD, 0x5D, 0xA3, 0x55, 0xE6, 0x63, 0x15, 0x56, 0x7B, 0x01, 0x26, 0x68, 0x5F, 0x11, 0xA3, 0x12, 0x37, 0x02, 0xA5, 0xD0, 0xB7, 0x73, 0x0C, 0x7C,
+ 0x97, 0xE1, 0xC6, 0x2F, 0x98, 0x82, 0x67, 0x2F, 0x5F, 0x3F, 0xBE, 0x32, 0x16, 0x25, 0x9D, 0x51, 0x48, 0x32, 0xCB, 0x42, 0xD1, 0x31, 0x07, 0xBE, 0x5D, 0xF8, 0xCD, 0x2C, 0x38, 0x0A, 0x33, 0x3B, 0x7B, 0x04, 0x84, 0xAE, 0x9C, 0xA7, 0x6B, 0x36, 0x39, 0x12, 0x87, 0x9D, 0x5B, 0x56, 0x00, 0x44, 0x11, 0xB1, 0xE2, 0x78, 0x14, 0x60, 0xF3, 0xE4, 0x1A, 0x08, 0x14, 0xC0, 0x9E, 0x49, 0x9F, 0xE0, 0x4C, 0xEC, 0x95, 0x15, 0x18, 0x48, 0x0E, 0xB9, 0x0B, 0x3A, 0xFE, 0x45, 0xB0, 0x2D, 0x0D, 0x4F, 0x94, 0x5A, 0x3C, 0x43, 0xB7, 0x40, 0x8E, 0x7B, 0xA2, 0x8E, 0x23, 0x9F, 0x75, 0x97, 0xE7, 0x21, 0x0D, 0xEB, 0xA3, 0x9D,
+ 0x6C, 0xC0, 0xDC, 0x73, 0xED, 0x15, 0x98, 0xE3, 0xE8, 0x32, 0x2C, 0x12, 0x92, 0x45, 0x25, 0x45, 0x76, 0x18, 0xF5, 0x97, 0x7F, 0xAC, 0xCE, 0xCF, 0x23, 0xF7, 0xD1, 0xCF, 0x06, 0xAB, 0x82, 0x96, 0x1F, 0xF8, 0x68, 0x4F, 0x5D, 0xE1, 0x09, 0xAA, 0xCB, 0xB3, 0x50, 0x85, 0x46, 0x72, 0x14, 0x6C, 0x49, 0x84, 0x57, 0x55, 0x00, 0x78, 0x3E, 0xD9, 0xAA, 0xBD, 0xCC, 0xE2, 0x7B, 0x18, 0xAA, 0x2E, 0x5D, 0xB9, 0x28, 0xEA, 0x8F, 0x8C, 0xFA, 0xB7, 0x06, 0x27, 0x07, 0x89, 0x41, 0x3F, 0x66, 0x1A, 0x91, 0xCA, 0xE9, 0xEC, 0x09, 0x12, 0x1C, 0x67, 0xB2, 0x2A, 0x8B, 0x4A, 0xF0, 0x97, 0x17, 0xDC, 0x3E, 0xCD, 0x9F, 0x03,
+ 0x15, 0xEF, 0x03, 0x84, 0x08, 0x4A, 0x73, 0xAE, 0xE4, 0x07, 0x30, 0x27, 0xF7, 0x25, 0x69, 0x9D, 0x6C, 0x7D, 0x81, 0x88, 0xCC, 0xFA, 0xD4, 0xC7, 0x64, 0x11, 0xC0, 0xC8, 0x2C, 0x23, 0xF6, 0xFF, 0x9B, 0xE3, 0xC8, 0x89, 0x85, 0x0B, 0x3E, 0x81, 0xD8, 0x9C, 0xBD, 0xD0, 0x2D, 0xCD, 0x15, 0xA9, 0x30, 0x84, 0xF7, 0x6D, 0xEF, 0x62, 0x3B, 0xA7, 0x8C, 0xC2, 0x93, 0x90, 0x6F, 0x91, 0xB4, 0x8A, 0x71, 0x4E, 0x41, 0x4E, 0x5C, 0x67, 0xB5, 0x49, 0xF8, 0x56, 0x3A, 0x83, 0x03, 0x4F, 0xB1, 0xF6, 0xB7, 0x31, 0x5B, 0x68, 0x26, 0x70, 0x89, 0xB1, 0x1E, 0x67, 0x4F, 0xBA, 0xE7, 0xD9, 0xDF, 0x91, 0xD8, 0xFB, 0x8A, 0xDD,
+ 0xB2, 0xD3, 0x4B, 0xBB, 0x9F, 0x5C, 0xA3, 0x04, 0x2C, 0x87, 0xBC, 0xD5, 0xBE, 0x8C, 0xD7, 0xCF, 0x9B, 0x72, 0x82, 0xA6, 0x99, 0xDA, 0xD7, 0x66, 0x48, 0xE7, 0x8F, 0xE9, 0x48, 0x56, 0x9D, 0xD2, 0xB9, 0x28, 0x84, 0x4F, 0x6A, 0x83, 0xB2, 0xB9, 0x4D, 0x91, 0x10, 0x58, 0x22, 0x4C, 0xE7, 0x9D, 0xC6, 0x0C, 0x74, 0xF4, 0x16, 0x58, 0x30, 0xB7, 0xB7, 0x96, 0x39, 0x6C, 0x5D, 0xFA, 0xB2, 0x03, 0x8C, 0x98, 0xD2, 0xC0, 0x64, 0xB8, 0x05, 0x29, 0x4F, 0xF0, 0x4C, 0x43, 0x48, 0xD3, 0xD8, 0xBD, 0xC7, 0xC1, 0xEA, 0x39, 0x2A, 0xDF, 0xD4, 0xDA, 0x79, 0x7C, 0xB9, 0x06, 0xC7, 0x10, 0x8D, 0x8B, 0xF1, 0xA8, 0x8E, 0x44,
+ 0x9E, 0x99, 0xFF, 0x81, 0x84, 0x8F, 0xD0, 0x38, 0xE1, 0xF0, 0x5A, 0x12, 0x5F, 0xC5, 0xA6, 0xED, 0x6D, 0xEE, 0xE7, 0x69, 0xC0, 0xA2, 0xB4, 0x13, 0xCA, 0x7A, 0x5D, 0xDE, 0x88, 0x75, 0xE7, 0xE2, 0x6D, 0x8A, 0xEC, 0x0F, 0x88, 0x3F, 0xE2, 0xCB, 0x60, 0xF0, 0x6A, 0xEC, 0xD0, 0xF4, 0x0D, 0x11, 0xC2, 0x84, 0x19, 0x67, 0x52, 0xAD, 0xC0, 0xC0, 0x20, 0x84, 0x6D, 0x7D, 0xEA, 0xD2, 0xF9, 0x3F, 0xE5, 0x58, 0x00, 0xED, 0x24, 0xD6, 0x50, 0x9B, 0x80, 0x80, 0x0A, 0x31, 0x81, 0xA8, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x02, 0x31, 0x00, 0x30, 0x13, 0x06, 0x09, 0x2A, 0x86, 0x48,
+ 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x15, 0x31, 0x06, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00, 0x30, 0x17, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x14, 0x31, 0x0A, 0x1E, 0x08, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x6F, 0x30, 0x69, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01, 0x31, 0x5C, 0x1E, 0x5A, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41, 0x00, 0x20, 0x00, 0x53, 0x00, 0x43, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x6C,
+ 0x00, 0x20, 0x00, 0x43, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61, 0x00, 0x70, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x30, 0x82, 0x02, 0xB7, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06, 0xA0, 0x82, 0x02, 0xA8, 0x30, 0x82, 0x02, 0xA4, 0x02, 0x01, 0x00, 0x30, 0x82, 0x02, 0x9D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01,
+ 0x06, 0x30, 0x0E, 0x04, 0x08, 0xB8, 0x22, 0xEA, 0x3C, 0x70, 0x6A, 0xFC, 0x39, 0x02, 0x02, 0x07, 0xD0, 0x80, 0x82, 0x02, 0x70, 0x76, 0xBE, 0x5B, 0xD5, 0x3D, 0x05, 0xC1, 0xDB, 0x10, 0xA3, 0x02, 0xBB, 0x7F, 0x0A, 0x8B, 0x54, 0xC1, 0x7D, 0x19, 0xDA, 0x7E, 0x82, 0xDF, 0xAD, 0x6B, 0x42, 0xC2, 0x95, 0x95, 0x00, 0x6E, 0x82, 0x77, 0xD5, 0x42, 0x6E, 0x21, 0xA2, 0x95, 0xB4, 0x98, 0xF5, 0xDD, 0x18, 0x6F, 0xC4, 0xF3, 0xB6, 0x93, 0xA0, 0x6C, 0xF4, 0x34, 0x7A, 0x48, 0x72, 0x08, 0xB1, 0x28, 0x51, 0x54, 0x10, 0x7F, 0x35, 0xB2, 0xE5, 0x89, 0x5C, 0x0A, 0x14, 0x31, 0x1C, 0x9D, 0xA9, 0xE4, 0x94, 0x91, 0x28, 0x65,
+ 0xC4, 0xE7, 0x5E, 0xA9, 0x37, 0x08, 0x3D, 0xB1, 0x16, 0x61, 0x9D, 0xA9, 0x44, 0x6F, 0x20, 0x0C, 0x55, 0xD7, 0xCC, 0x48, 0x82, 0x13, 0x5D, 0xE1, 0xBD, 0x9D, 0xCE, 0x64, 0x28, 0x6D, 0x69, 0x4E, 0x08, 0x53, 0x09, 0xE0, 0xCC, 0xA8, 0x79, 0x04, 0xCF, 0xFA, 0x35, 0x1C, 0xA6, 0x70, 0x37, 0x64, 0x70, 0x74, 0xF8, 0xD0, 0xC4, 0x34, 0x0F, 0x71, 0xEF, 0x57, 0xC2, 0x43, 0x7D, 0xFA, 0xE5, 0x1B, 0x8C, 0x15, 0xA5, 0x08, 0x60, 0x78, 0xAF, 0xDA, 0x36, 0xDF, 0x79, 0x2D, 0xD7, 0x54, 0x35, 0xD7, 0x8D, 0x99, 0xD5, 0x81, 0xEC, 0x6D, 0x9F, 0x2D, 0x5E, 0xF8, 0x48, 0x85, 0x50, 0x20, 0x7D, 0xBB, 0x16, 0x4E, 0x39, 0x64,
+ 0xB7, 0xBC, 0xED, 0xA9, 0x6A, 0x7A, 0x06, 0x09, 0x6B, 0xBC, 0x2C, 0x5A, 0xE1, 0x4F, 0xD4, 0xA9, 0x82, 0x83, 0x5B, 0xBD, 0xCE, 0x14, 0x31, 0x89, 0x66, 0xB3, 0x9C, 0x31, 0x23, 0x00, 0x4B, 0x02, 0x34, 0x85, 0x30, 0x39, 0x77, 0x80, 0x5D, 0x72, 0x0A, 0xCE, 0x43, 0x2A, 0x1F, 0x02, 0x09, 0xAB, 0x2D, 0x46, 0x3A, 0x1C, 0xD2, 0x7B, 0xF6, 0x02, 0x92, 0xCA, 0xDA, 0x26, 0x0C, 0xF8, 0xE2, 0x67, 0x7E, 0xE2, 0x55, 0xB1, 0x3F, 0x6A, 0x06, 0x65, 0x6D, 0x74, 0x98, 0x59, 0xE2, 0x8A, 0x1E, 0x61, 0x03, 0x4D, 0xFC, 0x68, 0x31, 0x6A, 0xE7, 0xCF, 0x52, 0x88, 0x8E, 0x06, 0x97, 0x77, 0xB3, 0x20, 0x7E, 0x09, 0x5D, 0x3B,
+ 0xAF, 0x56, 0xF4, 0xE8, 0x4C, 0x69, 0x09, 0xB9, 0x80, 0x38, 0xDC, 0x66, 0x2E, 0x06, 0xF6, 0xCB, 0x1F, 0x1B, 0xAD, 0x51, 0xFF, 0xFD, 0x38, 0x8D, 0x03, 0x90, 0xCF, 0x31, 0x01, 0x30, 0xEA, 0x48, 0x4C, 0xBB, 0x40, 0x87, 0x1D, 0x97, 0x6A, 0x56, 0x4C, 0xED, 0x07, 0x23, 0x45, 0x50, 0x2F, 0x56, 0xC9, 0x90, 0x79, 0x09, 0xC5, 0x45, 0xB9, 0xAD, 0x58, 0x2B, 0x4C, 0xA3, 0x01, 0xE0, 0x2D, 0xE5, 0x30, 0xBC, 0x54, 0xEC, 0x65, 0xB4, 0x79, 0x22, 0x7D, 0x15, 0xF6, 0x28, 0xCD, 0x84, 0x7E, 0x27, 0x95, 0xA1, 0xC7, 0x82, 0x6D, 0xFB, 0xDF, 0x03, 0xD9, 0x14, 0xFE, 0x0A, 0x06, 0x6F, 0x14, 0xFF, 0x8A, 0x27, 0x80, 0x36,
+ 0xDC, 0xBA, 0xAE, 0xDD, 0x44, 0x15, 0xA5, 0x6E, 0x64, 0x73, 0xBD, 0xFB, 0xAE, 0x6D, 0x6F, 0x42, 0x96, 0xDF, 0x90, 0xE5, 0x6A, 0x9B, 0x05, 0xAE, 0xD5, 0x0A, 0x22, 0x88, 0xD6, 0x5D, 0x4C, 0x7B, 0xB1, 0x3A, 0xFC, 0x0C, 0x32, 0x02, 0xB1, 0x18, 0x0D, 0xAF, 0xE0, 0xFE, 0x7E, 0x07, 0x96, 0x85, 0xBB, 0xC8, 0x21, 0x68, 0x12, 0xD4, 0xC8, 0xBF, 0x91, 0x47, 0xE2, 0xF3, 0xA5, 0xA3, 0x86, 0xE6, 0x30, 0x42, 0xF5, 0xA9, 0xB9, 0x48, 0xCB, 0x18, 0xE6, 0x64, 0x3B, 0xE0, 0x8E, 0xC3, 0x03, 0x45, 0xA0, 0xED, 0x1A, 0x09, 0xFF, 0xB3, 0x99, 0x14, 0x5F, 0xDA, 0x90, 0x58, 0x61, 0x8E, 0xF7, 0x0A, 0x00, 0xC7, 0x44, 0xE7,
+ 0x73, 0x78, 0xC4, 0x8B, 0x39, 0xCE, 0x70, 0x0E, 0x24, 0x03, 0x95, 0x94, 0x73, 0x76, 0x10, 0x7E, 0x4C, 0xFF, 0xCA, 0x49, 0x93, 0x89, 0xD4, 0x3E, 0x1A, 0x88, 0xCC, 0x48, 0xA7, 0x78, 0x2F, 0x83, 0x4F, 0x6C, 0x33, 0x55, 0xDD, 0x7F, 0x7D, 0x4D, 0xE5, 0xCD, 0x9C, 0x3D, 0x04, 0x1E, 0xC1, 0x9B, 0x6D, 0x7E, 0x7A, 0xAC, 0x93, 0x5E, 0x2B, 0xC3, 0x85, 0x36, 0x07, 0x66, 0xE8, 0xC9, 0xC0, 0xD1, 0x54, 0xF4, 0x4C, 0x6A, 0x02, 0x24, 0x9A, 0x7D, 0x10, 0xD9, 0x79, 0x94, 0x00, 0x64, 0x63, 0x36, 0xDC, 0x35, 0x0C, 0x8F, 0x79, 0xBA, 0xC7, 0x10, 0x76, 0xF8, 0x4A, 0xD3, 0x69, 0x95, 0x23, 0x89, 0x66, 0xC4, 0x5A, 0xE7,
+ 0xCE, 0x21, 0xBC, 0xCB, 0xF2, 0x4F, 0x92, 0x33, 0xE7, 0x89, 0xD6, 0x23, 0xF7, 0x67, 0x5B, 0x20, 0xD9, 0xDA, 0x1A, 0xD1, 0xF6, 0x9E, 0x01, 0x83, 0x51, 0xAF, 0x35, 0x43, 0xDD, 0x3A, 0xAB, 0xCA, 0x0E, 0xED, 0x2E, 0x4D, 0x1E, 0x91, 0xCF, 0x2E, 0xA9, 0x4D, 0x08, 0xD9, 0x48, 0x30, 0x37, 0x30, 0x1F, 0x30, 0x07, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x04, 0x14, 0xA2, 0xED, 0x05, 0x50, 0x89, 0x91, 0x1D, 0xEB, 0xF6, 0x57, 0x66, 0xAF, 0x70, 0x15, 0xDD, 0x1A, 0xA1, 0x94, 0xB7, 0xB2, 0x04, 0x14, 0x09, 0xE4, 0x0B, 0xEC, 0x1D, 0x93, 0x3E, 0x32, 0x94, 0x6A, 0x95, 0x36, 0xDD, 0xBA, 0x93, 0x9D, 0x75, 0xB6,
+ 0x3E, 0xF5 };
+
+ // wrap the object so that we can use the extensions and fail
+ class AttachableNativeObject : ICMAttachmentBearer
+ {
+ INativeObject nativeObj;
+
+ public AttachableNativeObject (INativeObject obj)
+ {
+ nativeObj = obj;
+ }
+
+ public IntPtr Handle
+ {
+ get { return nativeObj.Handle; }
+ }
+ }
+
+ protected virtual bool Skip (Type type)
+ {
+ return Skip (type.Name) || SkipDueToAttribute (type);
+ }
+
+ protected virtual bool Skip (string nativeName)
+ {
+ if (nativeName.Contains ("`")) {
+ nativeName = nativeName.Substring (0, nativeName.IndexOf ("`"));
+ }
+ if (nativeName.StartsWith ("CGPDF")) // all those types crash the app
+ return true;
+ switch (nativeName) {
+ case "CFMachPort":
+ case "CFMessagePort":
+ case "DispatchSource":
+ case "AudioConverter": // does crash the tests
+ case "AudioFile": // does crash the tests
+ case "CFHTTPAuthentication":
+ case "CFHTTPStream":
+ case "SystemSound": // does crash the tests
+ case "MusicPlayer": // does crash the tests
+ case "MusicTrack": // does crash the tests
+ case "AUGraph": // does crash the tests
+ case "CGFunction":
+ case "CGShading":
+ case "CVMetalTexture":
+ case "CVMetalTextureCache":
+ case "CTRun":
+ case "CTRunDelegate":
+ case "CGImageMetadata":
+ case "SecKeyChain": // static class
+ case "VTDecompressionSession":
+ case "Class": // makes no sense to test
+ case "Selector": // makes no sense to test
+ case "CFRunLoopSource":
+ case "CFRunLoop":
+ case "NSZone":
+ case "MusicSequence": // crashes tests
+ case "AudioBuffers": // crashes tests
+ case "CGContext":
+ case "AudioComponent":
+ case "AudioUnit":
+ case "AURenderEventEnumerator":
+ case "CGLayer":
+ case "CMFormatDescription":
+ case "CMAudioFormatDescription":
+ case "CMVideoFormatDescription":
+ case "CMBlockBuffer":
+ case "CMSampleBuffer":
+ case "CVBuffer": // DOES support the API, but it has its own version and is already in the bindings, so no need ATM
+ case "CVImageBuffer": // same as CVBuffer
+ case "CVPixelBuffer": // same as CVBuffer
+ case "MTAudioProcessingTap":
+ case "Protocol":
+ case "MidiObject": // causes crash
+ case "CMClockOrTimebase":
+ case "MidiClient":
+ case "MidiPort":
+ case "MidiEntity":
+ case "MidiDevice":
+ case "MidiEndpoint":
+ case "ABMultiValue":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected INativeObject GetINativeInstance (Type t)
+ {
+ var ctor = t.GetConstructor (Type.EmptyTypes);
+ if ((ctor != null) && !ctor.IsAbstract)
+ return ctor.Invoke (null) as INativeObject;
+
+ if (!NativeObjectInterfaceType.IsAssignableFrom (t))
+ throw new ArgumentException ("t");
+ switch (t.Name) {
+ case "CFAllocator":
+ return CFAllocator.SystemDefault;
+ case "CFBundle":
+ var bundles = CFBundle.GetAll ();
+ if (bundles.Length > 0)
+ return bundles [0];
+ else
+ throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
+ case "CFNotificationCenter":
+ return CFNotificationCenter.Darwin;
+ case "CFReadStream":
+ case "CFStream":
+ CFReadStream readStream;
+ CFWriteStream writeStream;
+ CFStream.CreatePairWithSocketToHost ("www.google.com", 80, out readStream, out writeStream);
+ return readStream;
+ case "CFWriteStream":
+ CFStream.CreatePairWithSocketToHost ("www.google.com", 80, out readStream, out writeStream);
+ return writeStream;
+ case "CFUrl":
+ return CFUrl.FromFile ("/etc");
+ case "AudioFile":
+ var path = Path.GetFullPath ("1.caf");
+ var af = AudioFile.Open (CFUrl.FromFile (path), AudioFilePermission.Read, AudioFileType.CAF);
+ return af;
+ case "CFHTTPMessage":
+ return CFHTTPMessage.CreateEmpty (false);
+ case "CGBitmapContext":
+ byte[] data = new byte [400];
+ using (CGColorSpace space = CGColorSpace.CreateDeviceRGB ()) {
+ return new CGBitmapContext (data, 10, 10, 8, 40, space, CGBitmapFlags.PremultipliedLast);
+ }
+ case "CGContextPDF":
+ var filename = Environment.GetFolderPath (Environment.SpecialFolder.CommonDocuments) + "/t.pdf";
+ using (var url = new NSUrl (filename))
+ return new CGContextPDF (url);
+ case "CGColorConverter":
+ var cvt = new CGColorConverterTriple () {
+ Space = CGColorSpace.CreateGenericRgb (),
+ Intent = CGColorRenderingIntent.Default,
+ Transform = CGColorConverterTransformType.ApplySpace
+ };
+ return new CGColorConverter (null, cvt, cvt, cvt);
+ case "CGDataConsumer":
+ using (NSMutableData destData = new NSMutableData ()) {
+ return new CGDataConsumer (destData);
+ }
+ case "CGDataProvider":
+ filename = "xamarin1.png";
+ return new CGDataProvider (filename);
+ case "CGFont":
+ return CGFont.CreateWithFontName ("Courier New");
+ case "CGPattern":
+ return new CGPattern (
+ new RectangleF (0, 0, 16, 16),
+ CGAffineTransform.MakeIdentity (),
+ 16, 16,
+ CGPatternTiling.NoDistortion,
+ true,
+ (cgc) => {});
+ case "CMBufferQueue":
+ return CMBufferQueue.CreateUnsorted (2);
+ case "CTFont":
+ CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes () {
+ FamilyName = "Courier",
+ StyleName = "Bold",
+ Size = 16.0f
+ };
+ using (var fd = new CTFontDescriptor (fda))
+ return new CTFont (fd, 10, CTFontOptions.Default);
+ case "CTFontCollection":
+ return new CTFontCollection (new CTFontCollectionOptions ());
+ case "CTFontDescriptor":
+ fda = new CTFontDescriptorAttributes ();
+ return new CTFontDescriptor (fda);
+ case "CTTextTab":
+ return new CTTextTab (CTTextAlignment.Left, 2);
+ case "CTTypesetter":
+ return new CTTypesetter (new NSAttributedString ("Hello, world",
+ new CTStringAttributes () {
+ ForegroundColorFromContext = true,
+ Font = new CTFont ("Arial", 24)
+ }));
+ case "CTFrame":
+ var framesetter = new CTFramesetter (new NSAttributedString ("Hello, world",
+ new CTStringAttributes () {
+ ForegroundColorFromContext = true,
+ Font = new CTFont ("Arial", 24)
+ }));
+ var bPath = UIBezierPath.FromRect (new RectangleF (0, 0, 3, 3));
+ return framesetter.GetFrame (new NSRange (0, 0), bPath.CGPath, null);
+ case "CTFramesetter":
+ return new CTFramesetter (new NSAttributedString ("Hello, world",
+ new CTStringAttributes () {
+ ForegroundColorFromContext = true,
+ Font = new CTFont ("Arial", 24)
+ }));
+ case "CTGlyphInfo":
+ return new CTGlyphInfo ("Zapfino", new CTFont ("Arial", 24), "Foo");
+ case "CTLine":
+ return new CTLine (new NSAttributedString ("Hello, world",
+ new CTStringAttributes () {
+ ForegroundColorFromContext = true,
+ Font = new CTFont ("Arial", 24)
+ }));
+ case "CGImageDestination":
+ var storage = new NSMutableData ();
+ return CGImageDestination.Create (new CGDataConsumer (storage), "public.png", 1);
+ case "CGImageMetadataTag":
+ using (NSString name = new NSString ("tagName"))
+ using (var value = new NSString ("value"))
+ return new CGImageMetadataTag (CGImageMetadataTagNamespaces.Exif, CGImageMetadataTagPrefixes.Exif, name, CGImageMetadataType.Default, value);
+ case "CGImageSource":
+ filename = "xamarin1.png";
+ return CGImageSource.FromUrl (NSUrl.FromFilename (filename));
+ case "SecPolicy":
+ return SecPolicy.CreateSslPolicy (false, null);
+ case "SecIdentity":
+ using (var options = NSDictionary.FromObjectAndKey (new NSString ("farscape"), SecImportExport.Passphrase)) {
+ NSDictionary[] array;
+ var result = SecImportExport.ImportPkcs12 (farscape_pfx, options, out array);
+ if (result != SecStatusCode.Success)
+ throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0} due to {1}.", t.Name, result));
+ return new SecIdentity (array [0].LowlevelObjectForKey (SecImportExport.Identity.Handle));
+ }
+ case "SecTrust":
+ X509Certificate x = new X509Certificate (mail_google_com);
+ using (var policy = SecPolicy.CreateSslPolicy (true, "mail.google.com"))
+ return new SecTrust (x, policy);
+ case "SslContext":
+ return new SslContext (SslProtocolSide.Client, SslConnectionType.Stream);
+ case "UIFontFeature":
+ return new UIFontFeature (CTFontFeatureNumberSpacing.Selector.ProportionalNumbers);
+ case "NetworkReachability":
+ return new NetworkReachability (IPAddress.Loopback, null);
+#if !__TVOS__
+ case "VTCompressionSession":
+ case "VTSession":
+ return VTCompressionSession.Create (1024, 768, CMVideoCodecType.H264, (sourceFrame, status, flags, buffer) => { });
+ case "VTFrameSilo":
+ return VTFrameSilo.Create ();
+ case "VTMultiPassStorage":
+ return VTMultiPassStorage.Create ();
+#endif
+ case "CFString":
+ return new CFString ("test");
+ case "DispatchQueue":
+ return new DispatchQueue ("com.example.subsystem.taskXYZ");
+ case "DispatchGroup":
+ return DispatchGroup.Create ();
+ case "CGColorSpace":
+ return CGColorSpace.CreateAcesCGLinear ();
+ case "CGGradient":
+ CGColor[] cArray = { UIColor.Black.CGColor, UIColor.Clear.CGColor, UIColor.Blue.CGColor };
+ return new CGGradient (null, cArray);
+ case "CGImage":
+ filename = "xamarin1.png";
+ using (var dp = new CGDataProvider (filename))
+ return CGImage.FromPNG (dp, null, false, CGColorRenderingIntent.Default);
+ case "CGColor":
+ return UIColor.Black.CGColor;
+ case "CMClock":
+ CMClockError ce;
+ CMClock clock = CMClock.CreateAudioClock (out ce);
+ if (ce == CMClockError.None)
+ return clock;
+ throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
+ case "CMTimebase":
+ clock = CMClock.CreateAudioClock (out ce);
+ if (ce == CMClockError.None) {
+ return new CMTimebase (clock);
+ }
+ throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
+ case "CVPixelBufferPool":
+ return new CVPixelBufferPool (
+ new CVPixelBufferPoolSettings (),
+ new CVPixelBufferAttributes (CVPixelFormatType.CV24RGB, 100, 50)
+ );
+ case "SecCertificate":
+ using (var cdata = NSData.FromArray (mail_google_com))
+ return new SecCertificate (cdata);
+ case "SecKey":
+ SecKey private_key;
+ SecKey public_key;
+ using (var record = new SecRecord (SecKind.Key)) {
+ record.KeyType = SecKeyType.RSA;
+ record.KeySizeInBits = 512; // it's not a performance test :)
+ SecKey.GenerateKeyPair (record.ToDictionary (), out public_key, out private_key);
+ return private_key;
+ }
+ case "SecAccessControl":
+ return new SecAccessControl (SecAccessible.WhenPasscodeSetThisDeviceOnly);
+ default:
+ throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
+ }
+ }
+
+ protected ICMAttachmentBearer GetInstance (Type t)
+ {
+ if (!CMAttachmentInterfaceType.IsAssignableFrom (t))
+ throw new ArgumentException ("t");
+ switch (t.Name) {
+ case "CMBlockBuffer":
+ CMBlockBufferError bbe;
+ var result = CMBlockBuffer.CreateEmpty (0, CMBlockBufferFlags.AssureMemoryNow, out bbe);
+ if (bbe == CMBlockBufferError.None)
+ return result;
+ else
+ throw new InvalidOperationException (string.Format ("Could not create the new instance {0}.", bbe.ToString ()));
+ case "CMSampleBuffer":
+ var pixelBuffer = new CVPixelBuffer (20, 10, CVPixelFormatType.CV24RGB);
+
+ CMFormatDescriptionError fde;
+ var desc = CMVideoFormatDescription.CreateForImageBuffer (pixelBuffer, out fde);
+
+ var sampleTiming = new CMSampleTimingInfo ();
+
+ CMSampleBufferError sbe;
+ var sb = CMSampleBuffer.CreateForImageBuffer (pixelBuffer, true, desc, sampleTiming, out sbe);
+ if (sbe == CMSampleBufferError.None)
+ return sb;
+ else
+ throw new InvalidOperationException (string.Format ("Could not create the new instance {0}.", sbe.ToString ()));
+ default:
+ throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
+ }
+ }
+
+ [Test]
+ // test that the tag classes DO support the attachments API.
+ public void CheckAttachments ()
+ {
+ var types = CMClockType.Assembly.GetTypes ()
+ .Where(t => CMAttachmentInterfaceType.IsAssignableFrom(t) && !t.IsInterface);
+ foreach (var t in types) {
+ ICMAttachmentBearer obj = GetInstance (t);
+ if (obj is NSObject)
+ continue;
+ Assert.That (obj.Handle, Is.Not.EqualTo (IntPtr.Zero), t.Name + ".Handle");
+ using (var attch = new CFString ("myAttch")) {
+ var mode = CMAttachmentMode.ShouldNotPropagate;
+ CMAttachmentMode otherMode;
+ obj.SetAttachment ("key", attch, CMAttachmentMode.ShouldNotPropagate);
+ using (var otherAttch = obj.GetAttachment ("key", out otherMode)) {
+ obj.RemoveAllAttachments ();
+ Assert.AreEqual (mode, otherMode);
+ Assert.IsNotNull (otherAttch, "For type {0}", t.Name);
+ Assert.AreEqual (attch.ToString (), otherAttch.ToString (), "For type {0}", t.Name);
+ }
+ }
+ if (t is IDisposable) {
+ var disposable = obj as IDisposable;
+ disposable.Dispose ();
+ }
+ }
+ }
+
+ [Test]
+ // test that the classes do not support the attachments API
+ public void CheckFailAttachments ()
+ {
+ // get all tupes that are public, native object but not NSobjects or DispatchSources and that are not interfaces or abstract classes
+ var types = CMClockType.Assembly.GetTypes ()
+ .Where(t => !t.IsNotPublic && !CMAttachmentInterfaceType.IsAssignableFrom(t)
+ && NativeObjectInterfaceType.IsAssignableFrom (t) && !t.IsSubclassOf (NSObjectType)
+ && !t.IsSubclassOf (DispatchSourceType) && !t.IsInterface && !t.IsAbstract);
+ foreach (var t in types) {
+ if (Skip (t))
+ continue;
+ var obj = new AttachableNativeObject (GetINativeInstance (t));
+ Assert.That (obj.Handle, Is.Not.EqualTo (IntPtr.Zero), t.Name + ".Handle");
+ using (var attch = new CFString ("myAttch")) {
+ var mode = CMAttachmentMode.ShouldNotPropagate;
+ CMAttachmentMode otherMode;
+ obj.SetAttachment ("key", attch, CMAttachmentMode.ShouldNotPropagate);
+ using (var otherAttch = obj.GetAttachment ("key", out otherMode)) {
+ obj.RemoveAllAttachments ();
+ Assert.Null (otherAttch, "For type {0}", t.Name);
+ }
+ }
+ if (t is IDisposable) {
+ var disposable = obj as IDisposable;
+ disposable.Dispose ();
+ }
+ }
+ }
+ }
+}
+
+#endif // !__WATCHOS__
diff --git a/tests/dont link/ApiClassPtrTest.cs b/tests/dont link/ApiClassPtrTest.cs
new file mode 100644
index 000000000000..fe469454094a
--- /dev/null
+++ b/tests/dont link/ApiClassPtrTest.cs
@@ -0,0 +1,120 @@
+//
+// Test fixture for class_ptr introspection tests
+//
+// Authors:
+// Alex Soto
+//
+// Copyright 2012-2014 Xamarin Inc.
+//
+using System;
+using System.Reflection;
+using System.Linq;
+
+using NUnit.Framework;
+using Xamarin.Utils;
+using System.Runtime.CompilerServices;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+namespace TouchUnit.Bindings {
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public abstract class ApiClassPtrTest : ApiBaseTest {
+
+ protected virtual bool Skip (Type type)
+ {
+ // skip delegate (and other protocol references)
+ foreach (object ca in type.GetCustomAttributes (false)) {
+ if (ca is ProtocolAttribute)
+ return true;
+ if (ca is ModelAttribute)
+ return true;
+ }
+ return SkipDueToAttribute (type);
+ }
+
+ Type GetExtendedType (Type extensionType)
+ {
+ var method =
+ (from m in extensionType.GetMethods (BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
+ where m.IsDefined (typeof (ExtensionAttribute), false)
+ select m).FirstOrDefault();
+
+ if (method != null) {
+ var paramType = method.GetParameters () [0].ParameterType;
+ if (paramType.Name == "String")
+ return typeof (NSString);
+ else
+ return paramType;
+ }
+ else
+ return null;
+ }
+
+ IntPtr GetClassPtrFromRegister (Type t)
+ {
+ var attribs = t.GetCustomAttributes (typeof (RegisterAttribute), true);
+ if (attribs.Length > 0) {
+ var register = ((RegisterAttribute) attribs [0]);
+ return Class.GetHandle (register.Name);
+ }
+ return IntPtr.Zero;
+ }
+
+ [Test]
+ public void VerifyClassPtr ()
+ {
+ foreach (Type t in Assembly.GetTypes ()) {
+ if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
+ continue;
+
+ if (t.ContainsGenericParameters)
+ continue;
+
+ if (Skip (t))
+ continue;
+
+ FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ if (fi == null)
+ continue;
+ IntPtr class_ptr = (IntPtr) fi.GetValue (null);
+ IntPtr register_class_ptr = GetClassPtrFromRegister (t);
+
+ Assert.AreEqual (class_ptr, register_class_ptr, "class_ptr and RegisterAttribute are different: " + t.Name);
+ }
+ }
+
+ [Test]
+ public void VerifyClassPtrCategories ()
+ {
+ foreach (Type t in Assembly.GetTypes().Where (t => t.IsClass && t.IsSealed && t.IsAbstract)) {
+ if (Skip (t))
+ continue;
+
+ FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ if (fi == null)
+ continue;
+ IntPtr class_ptr = (IntPtr)fi.GetValue (null);
+
+ var extendedType = GetExtendedType (t);
+ IntPtr extended_class_ptr;
+ if (extendedType == null)
+ extended_class_ptr = IntPtr.Zero;
+ else
+ extended_class_ptr = GetClassPtrFromRegister (extendedType);
+
+ Assert.AreEqual (class_ptr, extended_class_ptr, "class_ptr and RegisterAttribute from extended class are different: " + t.Name);
+ }
+ }
+ }
+}
+
diff --git a/tests/dont link/ApiTypoTest.cs b/tests/dont link/ApiTypoTest.cs
new file mode 100644
index 000000000000..ff74ec2529f2
--- /dev/null
+++ b/tests/dont link/ApiTypoTest.cs
@@ -0,0 +1,476 @@
+//
+// Test the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Paola Villarreal
+//
+// Copyright 2015 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using NUnit.Framework;
+#if XAMCORE_2_0
+using UIKit;
+using Foundation;
+#else
+using MonoTouch.UIKit;
+using MonoTouch.Foundation;
+#endif
+
+namespace TouchUnit.Bindings
+{
+ public abstract class ApiTypoTest : ApiBaseTest
+ {
+ protected ApiTypoTest ()
+ {
+ ContinueOnFailure = true;
+ }
+
+ public virtual bool Skip (Type baseType, string typo) {
+ return SkipAllowed (baseType.Name, null, typo);
+ }
+
+ public virtual bool Skip (MemberInfo methodName, string typo) {
+ return SkipAllowed (methodName.DeclaringType.Name, methodName.Name, typo);
+ }
+
+ HashSet allowed = new HashSet () {
+ "Aac",
+ "Accurracy",
+ "Achivements",
+ "Acos",
+ "Actionname",
+ "Activitiy",
+ "Addr",
+ "Adjustmentfor",
+ "Aifc",
+ "Aiff",
+ "Amete",
+ "Amr",
+ "Anglet",
+ "Arraycollation",
+ "Asin",
+ "Atan",
+ "Attrib",
+ "Attributevalue",
+ "Audiofile",
+ "Automounted",
+ "Autoredirect",
+ "Backface",
+ "Bary",
+ "Batc",
+ "Bim",
+ "Biquad",
+ "Bitangent",
+ "Blinn",
+ "Blit",
+ "Bokeh",
+ "Bsln",
+ "Bssid",
+ "Bzip",
+ "Cabac",
+ "Caf", // acronym: Core Audio Format
+ "Cancellable",
+ "Cavlc",
+ "Celp", // MPEG4ObjectID
+ "Characterteristic",
+ "Chromaticities",
+ "Ciff",
+ "Cinepak",
+ "Clearcoat",
+ "Colos",
+ "Commerical",
+ "Composable",
+ "Conflictserror",
+ "Connnect",
+ "Counterclock",
+ "Craete",
+ "Cubemap",
+ "Cmyk", // acronym: Cyan, magenta, yellow and key
+ "Daap",
+ "Dav",
+ "Dcip", // acronym: Digital Cinema Implementation Partners
+ "Deca",
+ "Decomposables",
+ "Deinterlace",
+ "Descendents",
+ "Descrete",
+ "Differental",
+ "Diffie",
+ "Directionfor",
+ "Dist",
+ "dlclose",
+ "dlerror",
+ "Dlfcn",
+ "dlopen",
+ "dlsym",
+ "Dng",
+ "Dns",
+ "Dont",
+ "Dop",
+ "Downsample",
+ "Downmix", // Sound terminology that means making a stereo mix from a 5.1 surround mix.
+ "Dpa",
+ "Dpad", // Directional pad (D-pad)
+ "Droste",
+ "Dtls",
+ "dy",
+ "Ebu",
+ "Ecc",
+ "Eof", // acronym End-Of-File
+ "Emagic",
+ "Emaili",
+ "Eppc",
+ "Exhange",
+ "Exp",
+ "Flipside",
+ "Formati",
+ "Fov",
+ "Framebuffer",
+ "Framesetter",
+ "Freq",
+ "Ftps",
+ "Func",
+ "Gadu",
+ "Geocoder",
+ "Gpp",
+ "Hdmi",
+ "Hdr",
+ "Hevc", // CMVideoCodecType / High Efficiency Video Coding
+ "Hfp",
+ "Hipass",
+ "Hls",
+ "Hrtf", // acronym used in AUSpatializationAlgorithm
+ "Hvxc", // MPEG4ObjectID
+ "Icq",
+ "Identd",
+ "Imagefor",
+ "Imap",
+ "Imaps",
+ "Img",
+ "Inser",
+ "Interac",
+ "Interframe",
+ "Interitem",
+ "Intermenstrual",
+ "Intoi",
+ "Ios",
+ "Ipp",
+ "Iptc",
+ "Ircs",
+ "Itu",
+ "Jfif",
+ "Json",
+ "Keyerror",
+ "Keyi",
+ "Keyspace",
+ "ks",
+ "Langauges",
+ "Ldaps",
+ "Lerp",
+ "Linecap",
+ "Lingustic",
+ "Lod",
+ "Lopass",
+ "Lowlevel",
+ "Matchingcoalesce",
+ "Metacharacters",
+ "Minification",
+ "Mobike", // acronym
+ "Morpher",
+ "Mtu", // acronym
+ "Mtc", // acronym
+ "Mul",
+ "Mult",
+ "Multipeer",
+ "Muxed",
+ "nfloat",
+ "nint",
+ "Nntps",
+ "Ntlm",
+ "Ntsc",
+ "nuint",
+ "Numbernumber",
+ "Nyquist",
+ "Objectfor",
+ "Occlussion",
+ "Ocurrences",
+ "Oid",
+ "Oneup", // TVElementKeyOneupTemplate
+ "Orthographyrange",
+ "ove",
+ "Paeth", // PNG filter
+ "Pausable",
+ "Pcl",
+ "Pcm",
+ "Pdu",
+ "Persistance",
+ "Pesented",
+ "Pfs", // acronym
+ "Pkcs",
+ "Placemark",
+ "Playthrough",
+ "Pointillize",
+ "Polyline",
+ "Popularimeter",
+ "Prerolls",
+ "Preseti",
+ "Propogate",
+ "Psec",
+ "Pvrtc", // MTLBlitOption - PowerVR Texture Compression
+ "Quaterniond",
+ "Qura",
+ "Reacquirer",
+ "Reinvitation",
+ "Reinvite",
+ "Replayable",
+ "Requestwith",
+ "Rgb",
+ "Rgba",
+ "Roi",
+ "Romm", // acronym: Reference Output Medium Metric
+ "Rpa",
+ "Rpn", // acronym
+ "Rssi",
+ "Rtsp",
+ "Scn",
+ "Sdk",
+ "Sdtv", // acronym: Standard Definition Tele Vision
+ "Seekable",
+ "Shadable",
+ "Sharegroup",
+ "Siemen",
+ "Sinh",
+ "Sint", // as in "Signed Integer"
+ "Slerp",
+ "Slomo",
+ "Smpte",
+ "Snapshotter",
+ "Snorm",
+ "Sobel",
+ "Spacei",
+ "Sqrt",
+ "Srgb",
+ "Ssid",
+ "Standarize",
+ "Stateful",
+ "Stateright",
+ "Subbeat",
+ "Subcardioid",
+ "Subentities",
+ "Subheadline",
+ "Submesh",
+ "Submeshes",
+ "Subpixel",
+ "Subsec",
+ "Superentity",
+ "Sym",
+ "Synchronizable",
+ "Tanh",
+ "Texcoord",
+ "Texel",
+ "th",
+ "Threadgroup",
+ "Threadgroups",
+ "Thumbstick",
+ "Timelapse",
+ "Timelapses",
+ "Tls",
+ "Tlv",
+ "Toi",
+ "Truncantion",
+ "Tweening",
+ "tx",
+ "ty",
+ "Udi",
+ "Udp",
+ "Unconfigured",
+ "Undecodable",
+ "Underrun",
+ "Unorm",
+ "Unprepare",
+ "Unproject",
+ "Uterance",
+ "Utf",
+ "Uti",
+ "Varispeed",
+ "Vergence",
+ "Vnode",
+ "Vpn",
+ "Whitespaces",
+ "Writeability",
+ "Xpc",
+ "xy",
+ "Xyz",
+ "yuvs",
+ "yx",
+ "yy",
+ "Yyy",
+#if !XAMCORE_2_0
+ // classic only mistakes - that should not change anymore
+ "Timetime",
+ "Rectfrom",
+ "Distancefrom",
+ "Calendarc",
+ "Negotiat",
+ "Trus",
+ "Placemarks",
+ "Chage",
+ "Elipse",
+ "intptr",
+ "rbool",
+ "rint",
+ "rfloat",
+ "rdouble",
+ "rintptr",
+ "cgsize",
+ "cgpoint",
+ "cgrect",
+ "nsrange",
+ "stret",
+ "monotouch",
+ "xamarin",
+ "Dimiss",
+ "Owneroptions",
+ "Delegat",
+ "Nibfor",
+ "Delegatequeue",
+ "Sispatch",
+#endif
+ };
+
+ // ease maintenance of the list
+ HashSet used = new HashSet ();
+
+ bool SkipAllowed (string typeName, string methodName, string typo)
+ {
+ if (allowed.Contains (typo)) {
+ used.Add (typo);
+ return true;
+ }
+ return false;
+ }
+
+ bool IsObsolete (MemberInfo mi)
+ {
+ if (mi == null)
+ return false;
+ if (mi.GetCustomAttributes (true).Any ())
+ return true;
+ return IsObsolete (mi.DeclaringType);
+ }
+
+ [Test]
+ public void TypoTest ()
+ {
+ var types = Assembly.GetTypes ();
+ int totalErrors = 0;
+ foreach (Type t in types) {
+ if (t.IsPublic && !IsObsolete (t)) {
+ string txt = NameCleaner (t.Name);
+ var typo = GetTypo (txt);
+ if (typo.Length > 0 ) {
+ if (!Skip (t, typo)) {
+ ReportError ("Typo in TYPE: {0} - {1} ", t.Name, typo);
+ totalErrors++;
+ }
+ }
+
+ var fields = t.GetFields ();
+ foreach (FieldInfo f in fields) {
+ if (!f.IsPublic && !f.IsFamily && !IsObsolete (f))
+ continue;
+
+ txt = NameCleaner (f.Name);
+ typo = GetTypo (txt);
+ if (typo.Length > 0) {
+ if (!Skip (f, typo)) {
+ ReportError ("Typo in FIELD name: {0} - {1}, Type: {2}", f.Name, typo, t.Name);
+ totalErrors++;
+ }
+ }
+ }
+
+ var methods = t.GetMethods ();
+ foreach (MethodInfo m in methods) {
+ if (!m.IsPublic && !m.IsFamily && !IsObsolete (m))
+ continue;
+
+ txt = NameCleaner (m.Name);
+ typo = GetTypo (txt);
+ if (typo.Length > 0) {
+ if (!Skip (m, typo)) {
+ ReportError ("Typo in METHOD name: {0} - {1}, Type: {2}", m.Name, typo, t.Name);
+ totalErrors++;
+ }
+ }
+#if false
+ var parameters = m.GetParameters ();
+ foreach (ParameterInfo p in parameters) {
+ txt = NameCleaner (p.Name);
+ typo = GetTypo (txt);
+ if (typo.Length > 0) {
+ ReportError ("Typo in PARAMETER Name: {0} - {1}, Method: {2}, Type: {3}", p.Name, typo, m.Name, t.Name);
+ totalErrors++;
+ }
+ }
+#endif
+ }
+ }
+ }
+#if false
+ // ease removal of unrequired values (but needs to be checked for every profile)
+ var unused = allowed.Except (used);
+ foreach (var typo in unused)
+ Console.WriteLine ("Unused entry \"{0}\"", typo);
+#endif
+ Assert.IsTrue ((totalErrors == 0), "We have {0} typos!", totalErrors);
+ }
+
+ public abstract string GetTypo (string txt);
+
+ static StringBuilder clean = new StringBuilder ();
+
+ static string NameCleaner (string name)
+ {
+ clean.Clear ();
+ foreach (char c in name) {
+ if (Char.IsUpper (c)) {
+ clean.Append (' ').Append (c);
+ continue;
+ }
+ if (Char.IsDigit (c)) {
+ clean.Append (' ');
+ continue;
+ }
+ switch (c) {
+ case '<':
+ case '>':
+ case '_':
+ clean.Append (' ');
+ break;
+ default:
+ clean.Append (c);
+ break;
+ }
+ }
+ return clean.ToString ();
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/AppDelegate.cs b/tests/dont link/AppDelegate.cs
new file mode 100644
index 000000000000..87c5c2f3b38d
--- /dev/null
+++ b/tests/dont link/AppDelegate.cs
@@ -0,0 +1,41 @@
+#if !__WATCHOS__
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+using MonoTouch.NUnit.UI;
+
+namespace DontLink
+{
+ [Register ("AppDelegate")]
+ public partial class AppDelegate : UIApplicationDelegate
+ {
+ static public TouchRunner Runner { get; private set; }
+
+ public override UIWindow Window { get; set; }
+
+ public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
+ {
+ // create a new window instance based on the screen size
+ Window = new UIWindow (UIScreen.MainScreen.Bounds);
+ Runner = new TouchRunner (Window);
+
+ // tests can be inside the main assembly
+ Runner.Add (Assembly.GetExecutingAssembly ());
+ Runner.Add (typeof (BundledResources.ResourcesTest).Assembly);
+
+ Window.RootViewController = new UINavigationController (Runner.GetViewController ());
+
+ // make the window visible
+ Window.MakeKeyAndVisible ();
+
+ return true;
+ }
+ }
+}
+#endif // !__WATCHOS__
diff --git a/tests/dont link/BoardingPass.pkpass b/tests/dont link/BoardingPass.pkpass
new file mode 100644
index 000000000000..f969c10258a5
Binary files /dev/null and b/tests/dont link/BoardingPass.pkpass differ
diff --git a/tests/dont link/CalendarTest.cs b/tests/dont link/CalendarTest.cs
new file mode 100644
index 000000000000..953645619b36
--- /dev/null
+++ b/tests/dont link/CalendarTest.cs
@@ -0,0 +1,42 @@
+// Copyright 2013 Xamarin Inc. All rights reserved.
+
+using System;
+using System.Globalization;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace DontLink.Calendars {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class CalendarTest {
+
+ // application must *NOT* be build with I18N.MidEast and I18N.Other (Thai)
+
+ [Test]
+ public void UmAlQura ()
+ {
+ var ci = CultureInfo.GetCultureInfo ("ar");
+ Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.UmAlQuraCalendar"), "Calendar");
+ }
+
+ [Test]
+ public void Hijri ()
+ {
+ var ci = CultureInfo.GetCultureInfo ("ps");
+ Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.HijriCalendar"), "Calendar");
+ }
+
+ [Test]
+ public void ThaiBuddhist ()
+ {
+ var ci = CultureInfo.GetCultureInfo ("th");
+ Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.ThaiBuddhistCalendar"), "Calendar");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/DontLinkRegressionTests.cs b/tests/dont link/DontLinkRegressionTests.cs
new file mode 100644
index 000000000000..6548d50a4c1c
--- /dev/null
+++ b/tests/dont link/DontLinkRegressionTests.cs
@@ -0,0 +1,174 @@
+//
+// Don't Link [Regression] Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+
+using MonoTouch;
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+using ObjCRuntime;
+#else
+using MonoTouch.UIKit;
+#endif
+using NUnit.Framework;
+
+namespace DontLink {
+
+ [FileIOPermission (SecurityAction.LinkDemand, AllLocalFiles = FileIOPermissionAccess.AllAccess)]
+ public class SecurityDeclarationDecoratedUserCode {
+
+ [FileIOPermission (SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.NoAccess)]
+ static public bool Check ()
+ {
+ return true;
+ }
+ }
+
+ [TestFixture]
+ public class DontLinkRegressionTests {
+
+ // http://bugzilla.xamarin.com/show_bug.cgi?id=587
+ // regressed: http://bugzilla.xamarin.com/show_bug.cgi?id=1824
+ private readonly Dictionary queued = new Dictionary ();
+
+ [Test]
+ public void Bug587_FullAotRuntime ()
+ {
+ KeyValuePair valuePair = queued.FirstOrDefault (delegate {return true; });
+ Assert.NotNull (valuePair);
+ // should not crash with System.ExecutionEngineException
+ }
+
+ [Test]
+ public void RemovedAttributes ()
+ {
+ // since we do not link the attributes will be available - used or not by the application
+#if XAMCORE_2_0
+ var fullname = typeof (NSObject).Assembly.FullName;
+ Assert.NotNull (Type.GetType ("ObjCRuntime.ThreadSafeAttribute, " + fullname), "ThreadSafeAttribute");
+#else
+ Assert.NotNull (Type.GetType ("MonoTouch.ObjCRuntime.SinceAttribute, monotouch"), "SinceAttribute");
+ Assert.NotNull (Type.GetType ("MonoTouch.ObjCRuntime.ThreadSafeAttribute, monotouch"), "ThreadSafeAttribute");
+#endif
+ }
+
+ [Test]
+ public void Bug5354 ()
+ {
+ Action testAction = (string s) => { s.ToString (); };
+ testAction.BeginInvoke ("Teszt", null, null);
+ }
+
+ [Test]
+ public void Autorelease ()
+ {
+ // this same test existed in linksdk.app and linkall.app to test the linker optimizing IL code
+ // around [Autorelease] decorated methods. However iOS7 changed it's behavior and returns null now
+ using (UIImage img = new UIImage ()) {
+#if __WATCHOS__
+ if (true) {
+#else
+ if (UIDevice.CurrentDevice.CheckSystemVersion (7, 0)) {
+#endif
+#if !__TVOS__
+ Assert.Null (img.StretchableImage (10, 10), "StretchableImage");
+#endif
+ Assert.Null (img.CreateResizableImage (new UIEdgeInsets (1, 2, 3, 4)), "CreateResizableImage");
+ } else {
+#if !__TVOS__
+ Assert.NotNull (img.StretchableImage (10, 10), "StretchableImage");
+#endif
+ Assert.NotNull (img.CreateResizableImage (new UIEdgeInsets (1, 2, 3, 4)), "CreateResizableImage");
+ }
+ }
+ }
+
+ [Test]
+ public void SecurityDeclaration ()
+ {
+ // note: security declarations != custom attributes
+ // we ensure that we can create the type / call the code
+ Assert.True (SecurityDeclarationDecoratedUserCode.Check (), "call");
+ // we ensure that both the permission and the flag are part of the final (non-linked) binary
+ Assert.NotNull (Type.GetType ("System.Security.Permissions.FileIOPermissionAttribute, mscorlib"), "FileIOPermissionAttribute");
+ Assert.NotNull (Type.GetType ("System.Security.Permissions.FileIOPermissionAccess, mscorlib"), "FileIOPermissionAccess");
+ }
+
+ [Test]
+ public void DefaultEncoding ()
+ {
+ // https://bugzilla.xamarin.com/show_bug.cgi?id=29928
+ var de = System.Text.Encoding.Default;
+ Assert.That (de.WebName, Is.EqualTo ("utf-8"), "Name");
+ Assert.True (de.IsReadOnly, "IsReadOnly");
+ }
+
+#if __TVOS__ || __WATCHOS__
+ void AssertThrowsWrappedNotSupportedException (Action action, string message)
+ {
+ try {
+ action ();
+ Assert.Fail ("No exception was thrown. " + message);
+ } catch (TargetInvocationException tie) {
+ var nse = tie.InnerException as TargetInvocationException;
+ if (nse != null)
+ Assert.Fail ("An exception was thrown, but {0} instead of NotSupportedException. " + message, tie.InnerException.GetType ().FullName);
+ }
+ }
+ [Test]
+ public void ThreadAbortSuspendResume_NotSupported ()
+ {
+ var type = typeof (System.Threading.Thread);
+ var instance = new System.Threading.Thread (() => { });
+
+ var all_methods = type.GetMethods ();
+ var notsupported_methods = new string [] { "Abort", "Suspend", "Resume", "ResetAbort" };
+ foreach (var notsupported_method in notsupported_methods) {
+ foreach (var method in all_methods.Where ((v) => v.Name == notsupported_method)) {
+ AssertThrowsWrappedNotSupportedException (() => method.Invoke (instance, new object [method.GetParameters ().Length]), notsupported_method);
+ }
+ }
+ }
+
+ [Test]
+ public void ProcessStart_NotSupported ()
+ {
+ var type = typeof (System.Diagnostics.Process);
+ var instance = new System.Diagnostics.Process ();
+
+ var all_methods = type.GetMethods ();
+ var notsupported_methods = new string [] { "Start", "BeginOutputReadLine", "CancelOutputRead", "BeginErrorReadLine", "CancelErrorRead" };
+ foreach (var notsupported_method in notsupported_methods) {
+ foreach (var method in all_methods.Where ((v) => v.Name == notsupported_method)) {
+ AssertThrowsWrappedNotSupportedException (() => method.Invoke (instance, new object [method.GetParameters ().Length]), notsupported_method);
+ }
+ }
+
+ var all_properties = type.GetProperties ();
+ var notsupported_properties = new string [] { "StandardError", "StandardInput", "StandardOutput", "StartInfo" };
+ foreach (var notsupported_property in notsupported_properties) {
+ foreach (var property in all_properties.Where ((v) => v.Name == notsupported_property)) {
+ if (property.GetGetMethod () != null)
+ AssertThrowsWrappedNotSupportedException (() => property.GetGetMethod ().Invoke (instance, new object [] {}), notsupported_property + " (getter)");
+ if (property.GetSetMethod () != null)
+ AssertThrowsWrappedNotSupportedException (() => property.GetSetMethod ().Invoke (instance, new object [] { null }), notsupported_property + " (setter)");
+ }
+
+ }
+ }
+#endif // __TVOS__ || __WATCHOS__
+ }
+}
diff --git a/tests/dont link/Info.plist b/tests/dont link/Info.plist
new file mode 100644
index 000000000000..563fba75b638
--- /dev/null
+++ b/tests/dont link/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ CFBundleDisplayName
+ DontLinkTest
+ CFBundleIdentifier
+ com.xamarin.dontlink
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 5.1.1
+
+
diff --git a/tests/dont link/Main.cs b/tests/dont link/Main.cs
new file mode 100644
index 000000000000..12c5bdd9b389
--- /dev/null
+++ b/tests/dont link/Main.cs
@@ -0,0 +1,24 @@
+#if !__WATCHOS__
+using System;
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+
+namespace dontlink
+{
+ public class Application
+ {
+ // This is the main entry point of the application.
+ static void Main (string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main (args, null, "AppDelegate");
+ }
+ }
+}
+#endif // !__WATCHOS__
diff --git a/tests/dont link/TableViewSourceTest.cs b/tests/dont link/TableViewSourceTest.cs
new file mode 100644
index 000000000000..571804cd9cea
--- /dev/null
+++ b/tests/dont link/TableViewSourceTest.cs
@@ -0,0 +1,60 @@
+//
+// UITableViewSourceTest
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012 Xamarin Inc. All rights reserved.
+//
+
+#if !__WATCHOS__
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+using NUnit.Framework;
+
+namespace DontLink.UIKit {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class TableViewSourceTest {
+
+ // UITableViewSource is MonoTouch specific and should include veverything from
+ // UITableViewDelegate and UITableViewDataSource - but it's easy to forget to
+ // update its members (e.g. bug 8298 for iOS6 additions).
+
+ // note: test executed inside the dontlink.app on purpose ;-)
+
+ [Test]
+ public void ValidateMembers ()
+ {
+ var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance;
+
+ var methods = new List ();
+ foreach (var mi in typeof (UITableViewDelegate).GetMethods (flags))
+ methods.Add (mi.ToString ());
+ foreach (var mi in typeof (UITableViewDataSource).GetMethods (flags))
+ methods.Add (mi.ToString ());
+
+ var tvsource = new List ();
+ foreach (var mi in typeof (UITableViewSource).GetMethods (flags))
+ tvsource.Add (mi.ToString ());
+
+ methods.RemoveAll (delegate (string name) {
+ return tvsource.Contains (name);
+ });
+ Assert.That (methods.Count, Is.EqualTo (0), "Incomplete bindings! " + String.Join (", ", methods));
+ }
+ }
+}
+
+#endif // !__WATCHOS__
diff --git a/tests/dont link/dont link.csproj b/tests/dont link/dont link.csproj
new file mode 100644
index 000000000000..1c26f957759d
--- /dev/null
+++ b/tests/dont link/dont link.csproj
@@ -0,0 +1,180 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 8.0.30703
+ 2.0
+ {208744BD-504E-47D7-9A98-1CF02454A6DA}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ dontlink
+ dont link
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;MONOTOUCH
+ prompt
+ 4
+ False
+ None
+ True
+ -v -v
+
+
+ i386
+
+
+ none
+ False
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ False
+ None
+ -v -v -gcc_flags="-weak_framework GameController"
+ i386
+
+
+ MONOTOUCH
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;MONOTOUCH
+ prompt
+ 4
+ False
+ True
+ iPhone Developer
+ None
+
+
+ -v -v --registrar:static
+ ARMv7
+
+
+ none
+ False
+ bin\iPhone\Release
+ prompt
+ 4
+ False
+ iPhone Developer
+ -v -v
+ True
+
+
+ None
+ ARMv7
+ MONOTOUCH
+
+
+ true
+ full
+ false
+ bin\iPhone\Debug
+ DEBUG;MONOTOUCH
+ prompt
+ 4
+ false
+ ARMv7
+
+
+ None
+ true
+ iPhone Developer
+ -v -v --registrar:static
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CoreSelectorTest.cs
+
+
+ ApiBaseTest.cs
+
+
+ ApiCtorInitTest.cs
+
+
+ ApiFieldTest.cs
+
+
+ ApiSelectorTest.cs
+
+
+ ApiSignatureTest.cs
+
+
+ ApiCoreImageFiltersTest.cs
+
+
+ ApiProtocolTest.cs
+
+
+ EnvironmentVariable.cs
+
+
+ ApiPInvokeTest.cs
+
+
+ ApiWeakPropertyTest.cs
+
+
+ PlatformInfo.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.caf
+
+
+
+
+ {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}
+ BundledResources
+
+
+
+
+ xamarin1.png
+
+
+
diff --git a/tests/dont link/iOSApiClassPtrTest.cs b/tests/dont link/iOSApiClassPtrTest.cs
new file mode 100644
index 000000000000..f7e2c5d46f01
--- /dev/null
+++ b/tests/dont link/iOSApiClassPtrTest.cs
@@ -0,0 +1,41 @@
+//
+// Test fixture for class_ptr introspection tests
+//
+// Authors:
+// Alex Soto
+//
+// Copyright 2012-2014 Xamarin Inc.
+//
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class iOSApiClassPtrTest : ApiClassPtrTest {
+
+ protected override bool Skip (Type type)
+ {
+ // While the following types are categories and contains a class_ptr
+ // they are not used at all as extensions since they are just used to expose
+ // static properties.
+ switch (type.Name) {
+ case "NSUrlUtilities_NSCharacterSet":
+ case "AVAssetTrackTrackAssociation":
+ return true;
+ }
+ return base.Skip (type);
+ }
+ }
+}
+
diff --git a/tests/dont link/iOSApiCtorInitTest.cs b/tests/dont link/iOSApiCtorInitTest.cs
new file mode 100644
index 000000000000..d2d319de6a2e
--- /dev/null
+++ b/tests/dont link/iOSApiCtorInitTest.cs
@@ -0,0 +1,316 @@
+//
+// Test the generated API `init` selectors are usable by developers
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+#if XAMCORE_2_0
+#if !__TVOS__
+using PassKit;
+#endif
+using Foundation;
+#if !__WATCHOS__
+using Metal;
+#endif
+using ObjCRuntime;
+using UIKit;
+#else
+using MonoTouch.PassKit;
+using MonoTouch.Foundation;
+using MonoTouch.Metal;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#endif
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiCtorInitTest : ApiCtorInitTest {
+
+ public iOSApiCtorInitTest ()
+ {
+ Class.ThrowOnInitFailure = false;
+ ContinueOnFailure = true;
+ //LogProgress = true;
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.Namespace) {
+ // all default ctor did not work and were replaced with [Obsolete("",true)] placeholders
+ // reflecting on those would create invalid instances (no handle) that crash the app
+ case "CoreBluetooth":
+ case "MonoTouch.CoreBluetooth":
+ return true;
+
+ case "CoreAudioKit":
+ case "MonoTouch.CoreAudioKit":
+ case "Metal":
+ case "MonoTouch.Metal":
+ // they works with iOS9 beta 4 (but won't work on older simulators)
+ if ((Runtime.Arch == Arch.SIMULATOR) && !CheckiOSOrTVOSSystemVersion (9,0))
+ return true;
+ break;
+#if !__WATCHOS__
+ case "MetalKit":
+ case "MonoTouch.MetalKit":
+ case "MetalPerformanceShaders":
+ case "MonoTouch.MetalPerformanceShaders":
+ if (Runtime.Arch == Arch.SIMULATOR)
+ return true;
+ // some devices don't support metal and that crash some API that does not check that, e.g. #33153
+ if (!CheckiOSOrTVOSSystemVersion (9,0) || (MTLDevice.SystemDefault == null))
+ return true;
+ break;
+#endif // !__WATCHOS__
+ }
+
+ switch (type.Name) {
+ // under iOS7 creating this type will crash later (after test execution) with a stack similar to:
+ // https://gist.github.com/rolfbjarne/457f78e20c8c31edef5c
+ case "EKCalendarChooserDelegate":
+ case "EKEventEditViewController":
+ return true;
+
+ // Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: There can only be one UIApplication instance.
+ case "UIApplication":
+ return true;
+ // Objective-C exception thrown. Name: NSInvalidArgumentException Reason: UISplitViewController is only supported when running under UIUserInterfaceIdiomPad
+ case "UISplitViewController":
+#if !__WATCHOS__
+ // Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: ADInterstitialAd is available on iPad only.
+ case "ADInterstitialAd":
+ return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone;
+#endif
+
+ case "UIVideoEditorController":
+ return true;
+ // shows an alert on the simulator
+ case "MFMessageComposeViewController":
+ return true;
+ // shows an alert on the device (if no email address is configured)
+ case "MFMailComposeViewController":
+ return true;
+
+#if !__TVOS__
+ // PassKit is not available on iPads
+ case "PKPassLibrary":
+ return !PKPassLibrary.IsAvailable;
+#endif // !__TVOS__
+
+
+ // default ctor started to throw on iOS7 - we should never have exposed it but, for API compatibility,
+ // we now have an "empty" obsolete ctor
+ case "UIFont":
+ return true;
+
+ case "NSUrlSessionConfiguration":
+ case "NSUrlSession":
+ // This crashes when arc frees this object at the end of the scope:
+ // { NSURLSession *var = [[NSURLSession alloc] init]; }
+ return true;
+
+ case "GKAchievementViewController":
+ case "GKLeaderboardViewController":
+ // technically available since 4.1 - however it got a new base class in 6.0
+ // and that new base class GKGameCenterViewController did not exists before 6.0
+ // which makes the type unusable in 5.x, ref: https://gist.github.com/spouliot/271b6230a3aa2b58bc6e
+ return !CheckiOSSystemVersion (6,0);
+
+ // mistake - we should not have exposed those default ctor and now we must live with them
+ case "GCControllerElement":
+ case "GCControllerAxisInput":
+ case "GCControllerButtonInput":
+ case "GCControllerDirectionPad":
+ case "GCGamepad":
+ case "GCExtendedGamepad":
+ case "GCController":
+ return true;
+
+ // default constructor are not working on iOS8 so we removed them
+ // and can't test them even in earlier iOS versions
+ case "JSManagedValue":
+ case "MKLocalSearch":
+ case "MKTileOverlayRenderer":
+ case "AVAssetResourceLoadingDataRequest":
+ case "CLBeaconRegion":
+ case "NSPersistentStoreCoordinator":
+ return true;
+
+ // Metal is not available on the (iOS8) simulator
+ case "CAMetalLayer":
+ return (Runtime.Arch == Arch.SIMULATOR);
+
+#if !XAMCORE_2_0
+ // from iOS8 (beta4) they do not return a valid handle
+ case "AVAssetResourceLoader":
+ case "AVAssetResourceLoadingRequest":
+ case "AVAssetResourceLoadingContentInformationRequest":
+ return true;
+ // Started with iOS8 on simulator (always) but it looks like it can happen on devices too
+ // NSInvalidArgumentException Use initWithAccessibilityContainer:
+ case "UIAccessibilityElement":
+ return CheckiOSSystemVersion (8,0);
+#endif
+ // in 8.2 beta 1 this crash the app (simulator) without giving any details in the logs
+ case "WKUserNotificationInterfaceController":
+ return true;
+
+ // Both reported in radar #21548819
+ // NSUnknownKeyException [ valueForUndefinedKey:]: this class is not key value coding-compliant for the key inputPoint2.
+ case "CIDepthOfField":
+ // NSUnknownKeyException [ valueForUndefinedKey:]: this class is not key value coding-compliant for the key inputCropAmount.
+ case "CISunbeamsGenerator":
+ return true;
+
+ case "MPMediaItemArtwork":
+ // NSInvalidArgumentException Reason: image must be non-nil
+ return true;
+ default:
+ return base.Skip (type);
+ }
+ }
+
+ static List do_not_dispose = new List ();
+
+ protected override void Dispose (NSObject obj, Type type)
+ {
+ switch (type.Name) {
+ // this crash the application after test completed their execution so we keep it alive
+ case "AVAudioRecorder":
+ case "AVCaptureConnection":
+ case "GKFriendRequestComposeViewController":
+ case "SKView":
+ // NSInvalidArgumentException *** -[__NSDictionaryM removeObjectForKey:]: key cannot be nil
+ case "SKTextureAtlas":
+ // fails under iOS5 with NSInvalidArgumentException Reason: -[__NSCFDictionary removeObjectForKey:]: attempt to remove nil key
+ case "NSBundle":
+ case "NSUrlConnection": // crash too (only on iOS5)
+ // iOS8 beta 5 -> SIGABRT (only on devices)
+ case "CABTMidiCentralViewController":
+ case "CABTMidiLocalPeripheralViewController":
+ do_not_dispose.Add (obj);
+ break;
+ // iOS 9 beta 1 - crash when disposed
+ case "MidiNetworkConnection":
+ case "WKNavigation":
+ case "CIImageAccumulator":
+ case "NEAppProxyTcpFlow":
+ case "NEAppProxyUdpFlow":
+ do_not_dispose.Add (obj);
+ break;
+ default:
+ base.Dispose (obj, type);
+ break;
+ }
+ }
+
+ protected override void CheckHandle (NSObject obj)
+ {
+ bool result = obj.Handle != IntPtr.Zero;
+ if (!result) {
+ string name = obj.GetType ().Name;
+ switch (name) {
+ // FIXME: it's not clear what's the alternative to 'init' and it could be because I have no phone device
+ case "CTCallCenter":
+ case "CTTelephonyNetworkInfo":
+ return;
+ // to avoid crashes we do not really create (natively) default instances (iOS gives them to us)
+ // for compatibility purpose - we should never had included the default .ctor in monotouch.dll
+ case "CAMediaTimingFunction":
+ case "CLHeading":
+ case "CLRegion":
+ case "CLPlacemark":
+ case "CMAccelerometerData":
+ case "CMLogItem":
+ case "CMAttitude":
+ case "CMDeviceMotion":
+ case "CMGyroData":
+ case "CMMagnetometerData":
+ return;
+ // under iOS5 only - MPMediaPickerController: Unable to access iPod library.
+ case "MPMediaPickerController":
+ return;
+ // re-enabled as an [Obsolete ("", true)] but it will crash if we create it (which we can since we use reflection)
+ case "NSTimer":
+ case "NSCompoundPredicate":
+ return;
+ // iOS9 - the instance was "kind of valid" before
+ case "PKPaymentAuthorizationViewController":
+ if (CheckiOSSystemVersion (9,0))
+ return;
+ break;
+ }
+ base.CheckHandle (obj);
+ }
+ }
+
+ protected override void CheckToString (NSObject obj)
+ {
+ string name = obj.GetType ().Name;
+ switch (name) {
+ // crash at at MonoTouch.Foundation.NSObject.get_Description () [0x0000b] in /mono/ios/monotouch-ios7/monotouch/src/Foundation/NSObject.g.cs:500
+ case "SKTexture":
+ case "MCSession":
+ // crash at at MonoTouch.Foundation.NSObject.get_Description () [0x0000b] in /Developer/MonoTouch/Source/monotouch/src/Foundation/NSObject.g.cs:554
+ case "AVPlayerItemTrack":
+ case "AVCaptureConnection":
+ return;
+ // worked before ios6.0 beta 1
+ case "AVComposition":
+ // new API in iOS7
+ case "AVAssetResourceLoadingDataRequest":
+ // Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Unable to create description in descriptionForLayoutAttribute_layoutItem_coefficient. Something is nil
+ case "NSLayoutConstraint":
+ // new in 6.0
+ case "AVAssetResourceLoadingRequest":
+ case "GKScoreChallenge": // Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[GKScoreChallenge challengeID]: unrecognized selector sent to instance 0x18acc340
+ case "GKAchievementChallenge": // Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[GKAchievementChallenge challengeID]: unrecognized selector sent to instance 0x160f4840
+ if (CheckiOSOrTVOSSystemVersion (6,0))
+ return;
+ break;
+ // crash (when asking `description`) under iOS5 (only) simulator
+ case "NSUrlConnection":
+ return;
+ // iOS 9 beta 1 - crash when called
+ case "WKFrameInfo":
+ case "WKNavigation":
+ case "WKNavigationAction":
+ if (CheckiOSSystemVersion (9,0))
+ return;
+ break;
+ default:
+ base.CheckToString (obj);
+ break;
+ }
+ }
+
+
+ protected override void CheckNSObjectProtocol (NSObject obj)
+ {
+ switch (obj.GetType ().Name) {
+ case "NSString":
+ // according to bots `isKindOf (null)` returns true before iOS 8, ref: #36726
+ if (!CheckiOSOrTVOSSystemVersion (8, 0))
+ return;
+ break;
+ }
+ base.CheckNSObjectProtocol (obj);
+ }
+
+ // notes:
+ // * Splitview controller is expected to have a view controller at index 0 before it's used!
+ // this happens when we dispose an empty UISplitViewController, harmless
+ }
+}
diff --git a/tests/dont link/iOSApiFieldTest.cs b/tests/dont link/iOSApiFieldTest.cs
new file mode 100644
index 000000000000..49d51fe84689
--- /dev/null
+++ b/tests/dont link/iOSApiFieldTest.cs
@@ -0,0 +1,144 @@
+//
+// Test the generated API fields (e.g. against typos or OSX-only values)
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#endif
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiFieldTest : ApiFieldTest {
+
+ public iOSApiFieldTest ()
+ {
+ ContinueOnFailure = true;
+ //LogProgress = true;
+ }
+
+ protected override bool Skip (Type type)
+ {
+ return base.Skip (type);
+ }
+
+ protected override bool Skip (PropertyInfo p)
+ {
+ switch (p.DeclaringType.Namespace) {
+ case "CoreAudioKit":
+ case "MonoTouch.CoreAudioKit":
+ case "Metal":
+ case "MonoTouch.Metal":
+ // they works with iOS9 beta 4 (but won't work on older simulators)
+ if ((Runtime.Arch == Arch.SIMULATOR) && !CheckiOSSystemVersion (9,0))
+ return true;
+ break;
+ case "MetalKit":
+ case "MonoTouch.MetalKit":
+ case "MetalPerformanceShaders":
+ case "MonoTouch.MetalPerformanceShaders":
+ if (Runtime.Arch == Arch.SIMULATOR)
+ return true;
+ break;
+ }
+
+ switch (p.Name) {
+ case "AutoConfigurationHTTPResponseKey": // kCFProxyAutoConfigurationHTTPResponseKey
+ case "CFNetworkProxiesProxyAutoConfigJavaScript": // kCFNetworkProxiesProxyAutoConfigJavaScript
+ return true;
+
+ // defined in Apple PDF (online) but not in the HTML documentation
+ // but also inside CLError.h from iOS 5.1 SDK...
+ case "ErrorUserInfoAlternateRegionKey": // kCLErrorUserInfoAlternateRegionKey
+ return true;
+
+ // documented since iOS 4.0 - but the symbols are not in the libraries (see specific unit tests)
+ case "MakerMinoltaDictionary": // kCGImagePropertyMakerMinoltaDictionary
+ case "MakerFujiDictionary": // kCGImagePropertyMakerFujiDictionary
+ case "MakerOlympusDictionary": // kCGImagePropertyMakerOlympusDictionary
+ case "MakerPentaxDictionary": // kCGImagePropertyMakerPentaxDictionary
+ return true;
+
+ // ImageIO: documented since iOS 4.3 but null in iOS5 (works on iOS 6.1)
+ // https://developer.apple.com/library/ios/releasenotes/General/iOS43APIDiffs/
+ case "ExifCameraOwnerName":
+ case "ExifBodySerialNumber":
+ case "ExifLensSpecification":
+ case "ExifLensMake":
+ case "ExifLensModel":
+ case "ExifLensSerialNumber":
+ return !CheckiOSOrTVOSSystemVersion (6,1);
+
+ // ImageIO: new in iOS 8 but returns nil (at least in beta 1) seems fixed in iOS9
+ case "PNGLoopCount":
+ case "PNGDelayTime":
+ case "PNGUnclampedDelayTime":
+ return !CheckiOSOrTVOSSystemVersion (9,0);
+
+ // CoreServices.CFHTTPMessage - document in 10.9 but returns null
+ case "_AuthenticationSchemeOAuth1":
+ return true;
+
+ // Apple does not ship a PushKit for every arch on some devices :(
+ case "Voip":
+ return Runtime.Arch == Arch.DEVICE;
+
+ default:
+ return base.Skip (p);
+ }
+ }
+
+ protected override bool Skip (string constantName)
+ {
+ switch (constantName) {
+ // grep ImageIO binary shows those symbols are not part of the binary
+ // that match older results (nil) when loading them (see above)
+ case "kCGImagePropertyAPNGLoopCount":
+ case "kCGImagePropertyAPNGDelayTime":
+ case "kCGImagePropertyAPNGUnclampedDelayTime":
+ case "kCGImagePropertyMakerFujiDictionary":
+ case "kCGImagePropertyMakerMinoltaDictionary":
+ case "kCGImagePropertyMakerOlympusDictionary":
+ case "kCGImagePropertyMakerPentaxDictionary":
+ //
+ case "kCFHTTPAuthenticationSchemeOAuth1":
+ return true;
+ // Apple does not ship a PushKit for every arch on some devices :(
+ case "PKPushTypeVoIP":
+ return Runtime.Arch == Arch.DEVICE;
+ // there's only partial support for metal on the simulator (on iOS9 beta 5) but most other frameworks
+ // that interop with it are not (yet) supported
+ case "kCVMetalTextureCacheMaximumTextureAgeKey":
+ case "MPSRectNoClip":
+ case "MTKTextureLoaderErrorDomain":
+ case "MTKTextureLoaderErrorKey":
+ case "MTKTextureLoaderOptionAllocateMipmaps":
+ case "MTKTextureLoaderOptionSRGB":
+ case "MTKTextureLoaderOptionTextureUsage":
+ case "MTKTextureLoaderOptionTextureCPUCacheMode":
+ case "MTKModelErrorDomain":
+ case "MTKModelErrorKey":
+ return Runtime.Arch == Arch.SIMULATOR;
+ default:
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/iOSApiPInvokeTest.cs b/tests/dont link/iOSApiPInvokeTest.cs
new file mode 100644
index 000000000000..03086b8c147e
--- /dev/null
+++ b/tests/dont link/iOSApiPInvokeTest.cs
@@ -0,0 +1,100 @@
+//
+// Test the existing of p/invoked symbols
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2014-2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+#else
+using MonoTouch;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#endif
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiPInvokeTest : ApiPInvokeTest {
+
+ protected override bool Skip (string symbolName)
+ {
+ bool simulator = Runtime.Arch == Arch.SIMULATOR;
+ switch (symbolName) {
+ // Metal support inside simulator is only available in recent iOS9 SDK
+#if !__WATCHOS__
+ case "MTLCreateSystemDefaultDevice":
+ return simulator && !UIDevice.CurrentDevice.CheckSystemVersion (9, 0);
+#endif
+ // still most Metal helpers are not available on the simulator (even when the framework is present, it's missing symbols)
+ case "MPSSupportsMTLDevice":
+ // neither are the CoreVideo extensions for Metal
+ case "CVMetalTextureGetTexture":
+ case "CVMetalTextureIsFlipped":
+ case "CVMetalTextureGetCleanTexCoords":
+ case "CVMetalTextureCacheCreate":
+ case "CVMetalTextureCacheFlush":
+ case "CVMetalTextureCacheCreateTextureFromImage":
+ case "MTKMetalVertexDescriptorFromModelIO":
+ case "MTKModelIOVertexDescriptorFromMetal":
+ case "MTKModelIOVertexFormatFromMetal":
+ case "MTKMetalVertexFormatFromModelIO":
+ return simulator;
+
+ // it's not needed for ARM64 and Apple does not have stubs for them in libobjc.dylib
+ case "objc_msgSend_stret":
+ case "objc_msgSendSuper_stret":
+ return IntPtr.Size == 8 && !simulator;
+
+ default:
+ return base.Skip (symbolName);
+ }
+ }
+
+ protected override bool SkipAssembly (Assembly a)
+ {
+ // we only want to check this on a version of iOS that
+ // 1. is the current SDK target (or a newer one)
+#if !__WATCHOS__
+ var sdk = new Version (Constants.SdkVersion);
+ if (!UIDevice.CurrentDevice.CheckSystemVersion (sdk.Major, sdk.Minor))
+ return true;
+#endif
+ // 2. on the real target for Xamarin.iOS.dll/monotouch.dll
+ // as the simulator miss some libraries and symbols
+ // but the rest of the BCL is fine to test
+ return (a == typeof (NSObject).Assembly && (Runtime.Arch == Arch.SIMULATOR));
+ }
+
+ [Test]
+ public void NUnitLite ()
+ {
+ var a = typeof (TestAttribute).Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+
+#if !__WATCHOS__
+ [Test]
+ public void MonoTouchDialog ()
+ {
+ // there's no direct reference to MTD - but it's there
+ var a = DontLink.AppDelegate.Runner.NavigationController.TopViewController.GetType ().Assembly;
+ if (!SkipAssembly (a))
+ Check (a);
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/iOSApiProtocolTest.cs b/tests/dont link/iOSApiProtocolTest.cs
new file mode 100644
index 000000000000..465fe26e0d2c
--- /dev/null
+++ b/tests/dont link/iOSApiProtocolTest.cs
@@ -0,0 +1,288 @@
+//
+// Test the generated API for common protocol support
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013-2015 Xamarin Inc.
+//
+
+using System;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+#if !__TVOS__
+using WatchConnectivity;
+#endif
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+using MonoTouch.WatchConnectivity;
+#endif
+using NUnit.Framework;
+
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiProtocolTest : ApiProtocolTest {
+
+ public iOSApiProtocolTest ()
+ {
+ ContinueOnFailure = true;
+ // LogProgress = true;
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.Namespace) {
+ case "MetalKit":
+ case "MonoTouch.MetalKit":
+ case "MetalPerformanceShaders":
+ case "MonoTouch.MetalPerformanceShaders":
+ if (Runtime.Arch == Arch.SIMULATOR)
+ return true;
+ break;
+ }
+
+ switch (type.Name) {
+ // Apple does not ship a PushKit for every arch on some devices :(
+ case "PKPushCredentials":
+ case "PKPushPayload":
+ case "PKPushRegistry":
+ if (Runtime.Arch != Arch.DEVICE)
+ return true;
+
+ // Requires iOS 8.2 or later in 32-bit mode
+ if (!CheckiOSSystemVersion (8, 2) && IntPtr.Size == 4)
+ return true;
+
+ break;
+ }
+
+ return base.Skip (type);
+ }
+
+ protected override bool Skip (Type type, string protocolName)
+ {
+ // some code cannot be run on the simulator (e.g. missing frameworks)
+ switch (type.Namespace) {
+ case "MonoTouch.Metal":
+ case "Metal":
+ case "MonoTouch.CoreAudioKit":
+ case "CoreAudioKit":
+ // they works with iOS9 beta 4 (but won't work on older simulators)
+ if ((Runtime.Arch == Arch.SIMULATOR) && !CheckiOSOrTVOSSystemVersion (9,0))
+ return true;
+ break;
+
+#if !__TVOS__
+ case "WatchConnectivity":
+ case "MonoTouch.WatchConnectivity":
+ if (!WCSession.IsSupported)
+ return true;
+ break;
+#endif // !__TVOS__
+ }
+
+ switch (type.Name) {
+ case "CAMetalLayer":
+ // that one still does not work with iOS9 beta 4
+ if (Runtime.Arch == Arch.SIMULATOR)
+ return true;
+ break;
+#if !XAMCORE_3_0
+ // mistake (base type) fixed by a breaking change
+ case "MFMailComposeViewControllerDelegate":
+ if (protocolName == "UINavigationControllerDelegate")
+ return true;
+ break;
+#endif
+ // special case: the Delegate property is id so we made A subclass B in managed
+ // but this test see the conformance is not correct
+ case "UIImagePickerControllerDelegate":
+ case "UIVideoEditorControllerDelegate":
+ if (protocolName == "UINavigationControllerDelegate")
+ return true;
+ break;
+ }
+
+ switch (protocolName) {
+ case "NSCoding":
+ switch (type.Name) {
+ case "GKPlayer":
+ case "GKLocalPlayer":
+ // NSSecureCoding is still undocumented, for iOS, and neither is NSCoding for OSX
+ // and it did not respond before 6.0 (when NSSecureCoding was introduced)
+ return !CheckiOSOrTVOSSystemVersion (6,0);
+ case "UITableViewDataSource":
+ // this is a *protocol( and we do not want to force people to conform to (an
+ // undocumented "requirement") NSCoding - as ObjC do not have to do this
+ return true;
+ // part of HomeKit are *privately* conforming to NSCoding
+ case "HMCharacteristic":
+ case "HMCharacteristicMetadata":
+ case "HMHome":
+ case "HMService":
+ case "HMAccessory":
+ case "HMActionSet":
+ case "HMCharacteristicWriteAction":
+ case "HMRoom":
+ case "HMServiceGroup":
+ case "HMTimerTrigger":
+ case "HMTrigger":
+ case "HMUser":
+ case "HMZone":
+ case "HMAccessoryCategory":
+ case "HMCharacteristicEvent":
+ case "HMEvent":
+ case "HMEventTrigger":
+ case "HMLocationEvent":
+ // new PassKit for payment also *privately* conforms to NSCoding
+ case "PKPayment":
+ case "PKPaymentSummaryItem":
+ case "PKShippingMethod":
+ case "PKPaymentRequest":
+ case "PKPaymentToken":
+ // iOS9
+ case "UIFont":
+ case "AVAssetTrackSegment":
+ case "AVComposition":
+ case "AVMutableComposition":
+ case "AVCompositionTrackSegment":
+ case "MKMapSnapshotOptions":
+ case "WCSessionFile":
+ case "WCSessionFileTransfer":
+ return true;
+ }
+ break;
+ case "NSSecureCoding":
+ switch (type.Name) {
+ // part of HomeKit are *privately* conforming to NSSecureCoding
+ case "HMCharacteristic":
+ case "HMCharacteristicMetadata":
+ case "HMHome":
+ case "HMService":
+ case "HMAccessory":
+ case "HMActionSet":
+ case "HMCharacteristicWriteAction":
+ case "HMRoom":
+ case "HMServiceGroup":
+ case "HMTimerTrigger":
+ case "HMTrigger":
+ case "HMUser":
+ case "HMZone":
+ case "HMAccessoryCategory":
+ case "HMCharacteristicEvent":
+ case "HMEvent":
+ case "HMEventTrigger":
+ case "HMLocationEvent":
+ return true;
+ // new PassKit for payment also *privately* conforms to NSCoding
+ case "PKPayment":
+ case "PKPaymentSummaryItem":
+ case "PKShippingMethod":
+ case "PKPaymentRequest":
+ case "PKPaymentToken":
+ // iOS9
+ case "UIFont":
+ case "AVAssetTrackSegment":
+ case "AVComposition":
+ case "AVMutableComposition":
+ case "AVCompositionTrackSegment":
+ case "MKMapSnapshotOptions":
+ case "NSTextTab":
+ case "WCSessionFile":
+ case "WCSessionFileTransfer":
+ return true;
+ }
+ break;
+ case "NSCopying":
+ switch (type.Name) {
+ // undocumented conformance (up to 7.0) and conformity varies between iOS versions
+ case "MKDirectionsRequest":
+ case "MPMediaItem":
+ case "MPMediaPlaylist":
+ case "MPMediaItemCollection":
+ case "MPMediaEntity":
+ return true; // skip
+ // new PassKit for payment also *privately* conforms to NSCoding
+ case "PKPaymentSummaryItem":
+ case "PKShippingMethod":
+ return true; // skip
+ // iOS9
+ case "ACAccount":
+ case "HKCategorySample":
+ case "HKCorrelation":
+ case "HKObject":
+ case "HKQuantitySample":
+ case "HKSample":
+ case "HKWorkout":
+ return true;
+ }
+ break;
+ case "UIAccessibilityIdentification":
+ // UIView satisfy the contract - but return false for conformance (and so does all it's subclasses)
+ return true;
+ case "UIAppearance":
+ // we added UIAppearance to some types that do not conform to it
+ // note: removing them cause the *Appearance types to be removed too
+ switch (type.Name) {
+ case "ABPeoplePickerNavigationController":
+ case "EKEventEditViewController":
+ case "GKAchievementViewController":
+ case "GKFriendRequestComposeViewController":
+ case "GKLeaderboardViewController":
+ case "GKTurnBasedMatchmakerViewController":
+ case "MFMailComposeViewController":
+ case "MFMessageComposeViewController":
+ return true;
+ }
+ break;
+ case "UITextInputTraits":
+ // UISearchBar conformance fails before 7.1 - reference bug #33333
+ if ((type.Name == "UISearchBar") && !CheckiOSOrTVOSSystemVersion (7,1))
+ return true;
+ break;
+#if !XAMCORE_3_0
+ case "UINavigationControllerDelegate":
+ switch (type.Name) {
+ case "ABPeoplePickerNavigationControllerDelegate": // 37180
+ return true;
+ }
+ break;
+#endif
+ case "GKSavedGameListener":
+ switch (type.Name) {
+ case "GKLocalPlayerListener": // 37180
+ return !CheckiOSOrTVOSSystemVersion (8, 0);
+ }
+ break;
+ }
+ return base.Skip (type, protocolName);
+ }
+
+ [Test]
+ public override void SecureCoding ()
+ {
+ if (!CheckiOSOrTVOSSystemVersion (6,0))
+ Assert.Inconclusive ("Requires iOS 6+");
+
+ base.SecureCoding ();
+ }
+
+ [Test]
+ public override void SupportsSecureCoding ()
+ {
+ if (!CheckiOSOrTVOSSystemVersion (6,0))
+ Assert.Inconclusive ("Requires iOS 6+");
+
+ base.SupportsSecureCoding ();
+ }
+ }
+}
diff --git a/tests/dont link/iOSApiSelectorTest.cs b/tests/dont link/iOSApiSelectorTest.cs
new file mode 100644
index 000000000000..1b9bb3ea62b8
--- /dev/null
+++ b/tests/dont link/iOSApiSelectorTest.cs
@@ -0,0 +1,610 @@
+//
+// Test the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+#if !__TVOS__
+using WatchConnectivity;
+#endif
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+using MonoTouch.WatchConnectivity;
+#endif
+using NUnit.Framework;
+
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiSelectorTest : CoreSelectorTest {
+
+ public iOSApiSelectorTest ()
+ {
+ ContinueOnFailure = true;
+ //LogProgress = true;
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.Namespace) {
+ // they don't answer on the simulator (Apple implementation does not work) but fine on devices
+ case "GameController":
+ case "MonoTouch.GameController":
+ return Runtime.Arch == Arch.SIMULATOR;
+
+ case "CoreAudioKit":
+ case "MonoTouch.CoreAudioKit":
+ case "Metal":
+ case "MonoTouch.Metal":
+ // they works with iOS9 beta 4 (but won't work on older simulators)
+ if ((Runtime.Arch == Arch.SIMULATOR) && !CheckiOSOrTVOSSystemVersion (9,0))
+ return true;
+ break;
+ case "MetalKit":
+ case "MonoTouch.MetalKit":
+ case "MetalPerformanceShaders":
+ case "MonoTouch.MetalPerformanceShaders":
+ if (Runtime.Arch == Arch.SIMULATOR)
+ return true;
+ break;
+
+ // Apple does not ship a PushKit for every arch on some devices :(
+// case "PushKit":
+// case "MonoTouch.PushKit":
+// if (Runtime.Arch == Arch.DEVICE)
+// return true;
+// break;
+#if !__TVOS__
+ case "WatchConnectivity":
+ case "MonoTouch.WatchConnectivity":
+ if (!WCSession.IsSupported)
+ return true;
+ break;
+#endif // !__TVOS__
+ }
+
+ switch (type.Name) {
+ // abstract superclass
+ case "UIBarItem":
+ return true;
+
+ // does not answer to anything ?
+ case "UILocalNotification":
+ return true;
+
+ // Metal is not available on the (iOS8) simulator
+ case "CAMetalLayer":
+ return (Runtime.Arch == Arch.SIMULATOR);
+
+ default:
+ return base.Skip (type);
+ }
+ }
+
+ protected override bool CheckResponse (bool value, Type actualType, MethodBase method, ref string name)
+ {
+ if (value)
+ return true;
+
+ var declaredType = method.DeclaringType;
+
+ switch (declaredType.Name) {
+ case "NSUrlSession":
+ switch (name) {
+ case "delegateQueue":
+ case "sessionDescription":
+ case "setSessionDescription:":
+ case "delegate":
+ // does not respond anymore but the properties works (see monotouch-test)
+ if (CheckiOSOrTVOSSystemVersion (9, 0))
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSessionTask":
+ switch (name) {
+ case "countOfBytesExpectedToReceive":
+ case "countOfBytesExpectedToSend":
+ case "countOfBytesReceived":
+ case "countOfBytesSent":
+ case "currentRequest":
+ case "error":
+ case "originalRequest":
+ case "response":
+ case "state":
+ case "taskDescription":
+ case "setTaskDescription:":
+ case "taskIdentifier":
+ // does not respond anymore but the properties works (see monotouch-test)
+ if (CheckiOSOrTVOSSystemVersion (9, 0))
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSessionConfiguration":
+ case "NSUrlSessionStreamTask":
+ // does not respond anymore but the properties works (see monotouch-test for a partial list)
+ if (CheckiOSOrTVOSSystemVersion (9, 0))
+ return true;
+ break;
+
+ case "AVAssetDownloadTask":
+ switch (name) {
+ case "currentRequest":
+ case "originalRequest":
+ case "response":
+ if (CheckiOSOrTVOSSystemVersion (9, 0))
+ return true;
+ break;
+ }
+ break;
+ case "CMSensorRecorder":
+ switch (name) {
+ // breaking change from Apple in iOS 9.3 betas
+ // https://trello.com/c/kqlEkPbG/30-24508290-cmsensorrecorder-breaking-change-re-opening-24231250
+ // https://trello.com/c/pKLOLjVJ/29-24231250-coremotion-api-removal-without-deprecation
+ case "accelerometerDataFromDate:toDate:":
+ case "recordAccelerometerForDuration:":
+ if (!CheckiOSOrTVOSSystemVersion (9, 3))
+ return true;
+ break;
+ }
+ break;
+ }
+
+ switch (name) {
+ // UIResponderStandardEditActions - stuffed inside UIResponder
+ case "cut:":
+ case "copy:":
+ case "paste:":
+ case "delete:":
+ case "select:":
+ case "selectAll:":
+ // A subclass of UIResponder typically implements this method...
+ case "toggleBoldface:":
+ case "toggleItalics:":
+ case "toggleUnderline:":
+ if (declaredType.Name == "UIResponder")
+ return true;
+ break;
+ case "makeTextWritingDirectionLeftToRight:":
+ case "makeTextWritingDirectionRightToLeft:":
+ // MonoTouch.AddressBookUI.ABNewPersonViewController
+ // MonoTouch.AddressBookUI.ABPeoplePickerNavigationController
+ // MonoTouch.AddressBookUI.ABPersonViewController
+ if (declaredType.Name == "UIResponder")
+ return true;
+ break;
+#if !XAMCORE_2_0
+ case "enableInputClicksWhenVisible":
+ // defined in UIInputViewAudioFeedback protocol
+ // meant to be added (not part of iOS) in custom UIView and defined (by default) by MonoTouch
+ if (declaredType.Name == "UIView")
+ return true;
+ break;
+ case "subtitle":
+ // exists because of MKAnnotation protocol
+ if (declaredType.Name == "MKPlacemark")
+ return true;
+ break;
+ case "setCoordinate:":
+ // exists because of MKAnnotation protocol
+ if (declaredType.Name == "MKShape" || declaredType.Name == "MKPlacemark")
+ return true;
+ break;
+ case "intersectsMapRect:":
+ // optional method of a protocol MKTileOverlay implements.
+ if (declaredType.Name == "MKTileOverlay")
+ return true;
+ break;
+#endif
+ case "autocapitalizationType":
+ case "setAutocapitalizationType:":
+ case "autocorrectionType":
+ case "setAutocorrectionType:":
+ case "keyboardType":
+ case "setKeyboardType:":
+ case "spellCheckingType":
+ case "setSpellCheckingType:":
+ // UITextInputTraits and UITextInputProtocol
+ if (declaredType.Name == "UITextField" || declaredType.Name == "UITextView")
+ return true;
+ if (CheckiOSOrTVOSSystemVersion (7,1) && declaredType.Name == "UISearchBar")
+ return true;
+ break;
+ case "keyboardAppearance":
+ case "setKeyboardAppearance:":
+ case "returnKeyType":
+ case "setReturnKeyType:":
+ case "enablesReturnKeyAutomatically":
+ case "setEnablesReturnKeyAutomatically:":
+ case "isSecureTextEntry":
+ case "setSecureTextEntry:":
+ // UITextInputTraits and UITextInput Protocol
+ switch (declaredType.Name) {
+ case "UITextField":
+ case "UITextView":
+ case "UISearchBar":
+ return true;
+ }
+ break;
+ case "textStylingAtPosition:inDirection:":
+ case "positionWithinRange:atCharacterOffset:":
+ case "characterOffsetOfPosition:withinRange:":
+ case "shouldChangeTextInRange:replacementText:":
+ // UITextInputTraits and UITextInputProtocol
+ if (declaredType.Name == "UITextField" || declaredType.Name == "UITextView")
+ return true;
+ // ignore UISearchBar before iOS8 - it did not really implement UITextInput
+ if (declaredType.Name == "UISearchBar" && !CheckiOSSystemVersion (8,0))
+ return true;
+ break;
+ case "dictationRecognitionFailed":
+ case "dictationRecordingDidEnd":
+ case "insertDictationResult:":
+ // iOS 5.1 and not every device (or simulator)
+ if (declaredType.Name == "UITextField" || declaredType.Name == "UITextView")
+ return true;
+ break;
+ // special case: see http://developer.apple.com/library/ios/#documentation/GLkit/Reference/GLKViewController_ClassRef/Reference/Reference.html
+ case "update":
+ if (declaredType.Name == "GLKViewController")
+ return true;
+ break;
+ case "thumbnailImageAtTime:timeOption:":
+ case "requestThumbnailImagesAtTimes:timeOption:":
+ case "cancelAllThumbnailImageRequests":
+ case "accessLog":
+ case "errorLog":
+ case "timedMetadata":
+ if (declaredType.Name == "MPMoviePlayerController")
+ return true;
+ break;
+ // deprecated (removed in iOS 3.2)
+ case "backgroundColor":
+ case "setBackgroundColor:":
+ case "movieControlMode":
+ case "setMovieControlMode:":
+ if (declaredType.Name == "MPMoviePlayerController")
+ return true;
+ break;
+ case "skipToNextItem":
+ case "skipToBeginning":
+ case "skipToPreviousItem":
+ case "setNowPlayingItem:":
+ if (actualType.Name == "MPMusicPlayerController")
+ return true;
+ break;
+ // deprecated (according to docs) but actually removed (test) in iOS 6
+ case "useApplicationAudioSession":
+ case "setUseApplicationAudioSession:":
+ if (declaredType.Name == "MPMoviePlayerController")
+ return CheckiOSSystemVersion (6,0);
+ break;
+
+ // iOS6 - headers says readwrite but they do not respond
+ case "setUUID:":
+ case "setIsPrimary:":
+ if (declaredType.Name == "CBMutableService")
+ return CheckiOSSystemVersion (6, 0);
+ if (declaredType.Name == "CBMutableCharacteristic")
+ return CheckiOSSystemVersion (9, 0);
+ break;
+
+ // documented since 4.0 - but does not answer on an iPad1 with 5.1.1
+ case "isAdjustingFocus":
+ if (declaredType.Name == "AVCaptureDevice")
+ return true;
+ break;
+
+ // GameKit: documented since 4.1 - but does not answer
+ case "alias":
+ if (declaredType.Name == "GKPlayer")
+ return true;
+ break;
+ case "playerID":
+ switch (declaredType.Name) {
+ case "GKPlayer":
+ case "GKScore":
+ case "GKTurnBasedParticipant": // iOS 5
+ return true;
+ }
+ break;
+ case "category":
+ case "setCategory:":
+ case "date":
+ case "formattedValue":
+ case "rank":
+ case "value":
+ case "setValue:":
+ case "context": // iOS5
+ case "setContext:": // iOS5
+ if (declaredType.Name == "GKScore")
+ return true;
+ break;
+ case "isUnderage":
+ if (declaredType.Name == "GKLocalPlayer")
+ return true;
+ break;
+ case "identifier":
+ if (declaredType.Name == "GKAchievement" || declaredType.Name == "GKAchievementDescription")
+ return true;
+ break;
+ case "setIdentifier:":
+ case "percentComplete":
+ case "setPercentComplete:":
+ case "lastReportedDate":
+ case "setLastReportedDate:":
+ if (declaredType.Name == "GKAchievement")
+ return true;
+ break;
+ case "achievedDescription":
+ case "isHidden":
+ case "maximumPoints":
+ case "title":
+ case "unachievedDescription":
+ if (declaredType.Name == "GKAchievementDescription")
+ return true;
+ break;
+ // 5.0
+ case "lastTurnDate":
+ case "matchOutcome":
+ case "setMatchOutcome:":
+ if (declaredType.Name == "GKTurnBasedParticipant")
+ return true;
+ break;
+ case "creationDate":
+ case "matchData":
+ case "message":
+ case "setMessage:":
+ if (declaredType.Name == "GKTurnBasedMatch")
+ return true;
+ break;
+
+ // iOS6 - protocols for UICollectionView
+ case "numberOfSectionsInCollectionView:":
+ case "collectionView:viewForSupplementaryElementOfKind:atIndexPath:":
+ case "collectionView:shouldHighlightItemAtIndexPath:":
+ case "collectionView:didHighlightItemAtIndexPath:":
+ case "collectionView:didUnhighlightItemAtIndexPath:":
+ case "collectionView:shouldSelectItemAtIndexPath:":
+ case "collectionView:shouldDeselectItemAtIndexPath:":
+ case "collectionView:didSelectItemAtIndexPath:":
+ case "collectionView:didDeselectItemAtIndexPath:":
+ case "collectionView:didEndDisplayingCell:forItemAtIndexPath:":
+ case "collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:":
+ case "collectionView:shouldShowMenuForItemAtIndexPath:":
+ case "collectionView:canPerformAction:forItemAtIndexPath:withSender:":
+ case "collectionView:performAction:forItemAtIndexPath:withSender:":
+ // which also inherits from UIScrollViewDelegate
+ case "scrollViewDidScroll:":
+ case "scrollViewWillBeginDragging:":
+ case "scrollViewDidEndDragging:willDecelerate:":
+ case "scrollViewWillBeginDecelerating:":
+ case "scrollViewDidEndDecelerating:":
+ case "scrollViewDidEndScrollingAnimation:":
+ case "viewForZoomingInScrollView:":
+ case "scrollViewShouldScrollToTop:":
+ case "scrollViewDidScrollToTop:":
+ case "scrollViewDidEndZooming:withView:atScale:":
+ case "scrollViewDidZoom:":
+ case "scrollViewWillBeginZooming:withView:":
+ case "scrollViewWillEndDragging:withVelocity:targetContentOffset:":
+ if (declaredType.Name == "UICollectionViewController")
+ return CheckiOSOrTVOSSystemVersion (6,0);
+ break;
+
+ // failing (check why)
+ case "initialLayoutAttributesForInsertedItemAtIndexPath:":
+ case "initialLayoutAttributesForInsertedSupplementaryElementOfKind:atIndexPath:":
+ case "finalLayoutAttributesForDeletedItemAtIndexPath:":
+ case "finalLayoutAttributesForDeletedSupplementaryElementOfKind:atIndexPath:":
+ if (declaredType.Name == "UICollectionViewLayout")
+ return CheckiOSSystemVersion (6,0);
+ break;
+
+ // This is implemented by internal concrete classes of NSFileHandle
+ case "readInBackgroundAndNotify":
+ case "readInBackgroundAndNotifyForModes:":
+ case "readToEndOfFileInBackgroundAndNotifyForModes:":
+ case "readToEndOfFileInBackgroundAndNotify":
+ case "acceptConnectionInBackgroundAndNotifyForModes:":
+ case "acceptConnectionInBackgroundAndNotify":
+ case "waitForDataInBackgroundAndNotifyForModes:":
+ case "waitForDataInBackgroundAndNotify":
+ if (declaredType.Name == "NSFileHandle")
+ return true;
+ break;
+
+ // UITableViewController conforms to both UITableViewDelegate and UITableViewDataSource
+ case "tableView:canEditRowAtIndexPath:":
+ case "tableView:canMoveRowAtIndexPath:":
+ case "sectionIndexTitlesForTableView:":
+ case "tableView:sectionForSectionIndexTitle:atIndex:":
+ case "tableView:commitEditingStyle:forRowAtIndexPath:":
+ case "tableView:moveRowAtIndexPath:toIndexPath:":
+ case "tableView:willDisplayCell:forRowAtIndexPath:":
+ case "tableView:accessoryTypeForRowWithIndexPath:":
+ case "tableView:accessoryButtonTappedForRowWithIndexPath:":
+ case "tableView:willSelectRowAtIndexPath:":
+ case "tableView:willDeselectRowAtIndexPath:":
+ case "tableView:didSelectRowAtIndexPath:":
+ case "tableView:didDeselectRowAtIndexPath:":
+ case "tableView:editingStyleForRowAtIndexPath:":
+ case "tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:":
+ case "tableView:shouldIndentWhileEditingRowAtIndexPath:":
+ case "tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:":
+ case "tableView:shouldShowMenuForRowAtIndexPath:":
+ case "tableView:canPerformAction:forRowAtIndexPath:withSender:":
+ case "tableView:performAction:forRowAtIndexPath:withSender:":
+ case "tableView:willDisplayHeaderView:forSection:":
+ case "tableView:willDisplayFooterView:forSection:":
+ case "tableView:didEndDisplayingCell:forRowAtIndexPath:":
+ case "tableView:didEndDisplayingHeaderView:forSection:":
+ case "tableView:didEndDisplayingFooterView:forSection:":
+ case "tableView:shouldHighlightRowAtIndexPath:":
+ case "tableView:didHighlightRowAtIndexPath:":
+ case "tableView:didUnhighlightRowAtIndexPath:":
+ // iOS7
+ case "tableView:estimatedHeightForRowAtIndexPath:":
+ case "tableView:estimatedHeightForHeaderInSection:":
+ case "tableView:estimatedHeightForFooterInSection:":
+ // iOS 8
+ case "tableView:editActionsForRowAtIndexPath:":
+ if (declaredType.Name == "UITableViewController")
+ return true;
+ break;
+
+ // iOS7 beta issue ? remains in beta 5 / sim
+ // MCSession documents the cancelConnectPeer: selector but it does not answer
+ case "cancelConnectPeer:":
+ // CBCharacteristic documents the selector but does not respond
+ case "subscribedCentrals":
+ // UIPrintFormatter header attributedText says the API is not approved yet - and it does not respond
+ case "attributedText":
+ case "setAttributedText:":
+ // UISplitViewController
+ case "splitViewControllerSupportedInterfaceOrientations:":
+ case "splitViewControllerPreferredInterfaceOrientationForPresentation:":
+ return true;
+
+ case "color":
+ case "setColor:":
+ case "font":
+ case "setFont:":
+ case "text":
+ case "setText:":
+ case "textAlignment":
+ case "setTextAlignment:":
+ // iOS7 GM a "no text" instance does not answer to the selector (but you can call them)
+ if (declaredType.Name == "UISimpleTextPrintFormatter")
+ return true;
+ break;
+
+ case "copyWithZone:":
+ switch (declaredType.Name) {
+ // not conforming to NSCopying in 5.1 SDK
+ case "UIFont":
+ return !CheckiOSSystemVersion (6,0);
+ // not conforming to NSCopying before 7.0 SDK
+ case "CBPeripheral":
+ return !CheckiOSSystemVersion (7,0);
+ // not conforming to NSCopying before 8.0 SDK
+ case "AVMetadataFaceObject":
+ return !CheckiOSSystemVersion (8,0);
+ // not conforming to NSCopying before 8.2 SDK
+ case "HKUnit":
+ return !CheckiOSSystemVersion (8,2);
+ case "HKBiologicalSexObject":
+ case "HKBloodTypeObject":
+ return !CheckiOSSystemVersion (9,0);
+ }
+ break;
+
+ // on iOS8.0 this does not work on the simulator (but works on devices)
+ case "language":
+ if (declaredType.Name == "AVSpeechSynthesisVoice" && CheckiOSSystemVersion (8,0) && Runtime.Arch == Arch.SIMULATOR)
+ return true;
+ break;
+
+ // new, optional members of UIDynamicItem protocol in iOS9
+ case "collisionBoundingPath":
+ case "collisionBoundsType":
+ switch (declaredType.Name) {
+ case "UICollectionViewLayoutAttributes":
+ case "UIView":
+ case "UIDynamicItemGroup":
+ return true;
+ }
+ break;
+
+ // SceneKit integration with Metal is not working on simulators (at least for iOS9 beta 5)
+ case "currentRenderCommandEncoder":
+ case "colorPixelFormat":
+ case "commandQueue":
+ case "depthPixelFormat":
+ case "device":
+ case "stencilPixelFormat":
+ switch (declaredType.Name) {
+ case "SCNRenderer":
+ case "SCNView":
+ return Runtime.Arch == Arch.SIMULATOR;
+ }
+ break;
+
+#if XAMCORE_2_0
+ // some types adopted NS[Secure]Coding after the type was added
+ // and for unified that's something we generate automatically (so we can't put [iOS] on them)
+ case "encodeWithCoder:":
+ switch (declaredType.Name) {
+ // UITextInputMode was added in 4.2 but conformed to NSSecureCoding only from 7.0+
+ case "UITextInputMode":
+ return !CheckiOSSystemVersion (7,0);
+ // iOS9
+ case "HKBiologicalSexObject":
+ case "HKBloodTypeObject":
+ return !CheckiOSSystemVersion (9,0);
+ }
+ break;
+#else
+ // that was a binding mistake - the API should not have been exposed (not in the header file)
+ // we'll ignore them for compat - but won't provide them in the new assemblies
+ case "backgroundImageForBarMetrics:":
+ case "setBackgroundImage:forBarMetrics:":
+ if (declaredType.Name == "UISearchBar" && CheckiOSSystemVersion (8,0))
+ return true;
+ break;
+#endif
+ }
+
+ return base.CheckResponse (value, actualType, method, ref name);
+ }
+
+ protected override bool CheckStaticResponse (bool value, Type actualType, Type declaredType, ref string name)
+ {
+ switch (name) {
+ // new API in iOS9 beta 5 but is does not respond when queried - https://bugzilla.xamarin.com/show_bug.cgi?id=33431
+ case "geometrySourceWithBuffer:vertexFormat:semantic:vertexCount:dataOffset:dataStride:":
+ switch (declaredType.Name) {
+ case "SCNGeometrySource":
+ return true;
+ }
+ break;
+ }
+ return base.CheckStaticResponse (value, actualType, declaredType, ref name);
+ }
+
+ static List do_not_dispose = new List ();
+
+ protected override void Dispose (NSObject obj, Type type)
+ {
+ switch (type.Name) {
+ // this crash the application after test completed their execution so we keep them alive
+ case "GKFriendRequestComposeViewController":
+ case "PKAddPassesViewController":
+ case "SKView":
+ do_not_dispose.Add (obj);
+ break;
+ default:
+ base.Dispose (obj, type);
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/iOSApiSignatureTest.cs b/tests/dont link/iOSApiSignatureTest.cs
new file mode 100644
index 000000000000..c1b5a7f7eeb0
--- /dev/null
+++ b/tests/dont link/iOSApiSignatureTest.cs
@@ -0,0 +1,181 @@
+//
+// iOS tests for the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+#if XAMCORE_2_0
+using ObjCRuntime;
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+
+namespace MonoTouchFixtures{
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiSignatureTest : ApiSignatureTest {
+
+ public iOSApiSignatureTest ()
+ {
+ ContinueOnFailure = true;
+ //LogProgress = true;
+ }
+
+ protected override int Size (Type t, bool simd = false)
+ {
+ switch (t.Name) {
+ // rdar 21375616 - Breaking change with EventKit[UI] enum base type
+ // EventKit.EK* enums are anonymous enums in 10.10 and iOS 8, but an NSInteger in 10.11 and iOS 9.
+ case "EKCalendarChooserSelectionStyle":
+ case "EKCalendarChooserDisplayStyle":
+ if (!IsOSX11OrIOS9)
+ return 4;
+ break;
+ }
+ return base.Size (t, simd);
+ }
+
+ protected override bool Skip (Type type, MethodBase method, string selector)
+ {
+ switch (type.Name) {
+ case "UIAlertView":
+ // variable length parameters ...
+ if (selector == "initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:")
+ return true;
+ break;
+ case "UIViewController":
+ switch (selector) {
+ // offically added in 6.0 - but retroactively supported in iOS5 (including documentation)
+ // the code works (see monotouch-test.app) but Apple changed their return value in 6.0
+ // (they used to return `bool`)
+ case "beginAppearanceTransition:animated:":
+ case "endAppearanceTransition":
+ if (!CheckiOSOrTVOSSystemVersion (6,0))
+ return true;
+ break;
+ }
+ break;
+ case "NKIssue":
+ // Apple "promoted" this to `NSInteger` in iOS8 but this already existed (as a 32bits value) in iOS 7.x
+ // sadly, and even with a bug report with a few exchanges, this was not fixed before iOS8 GM :-(
+ // 64bits application for iOS 7.x will be uncommon so we prefer to be forward compatible
+ if (selector == "status")
+ return !CheckiOSSystemVersion (8,0);
+ break;
+ case "CMMotionManager":
+ // iOS 8.3 changed CMMotionManager from 4 to 8 bytes on 64bits CPU and we have to follow that breaking
+ // change unless Apple revert that before final. [radar 20295259]
+ if ((IntPtr.Size == 4) || CheckiOSSystemVersion (8,3))
+ return false;
+ // which means iOS 8.2 (and earlier can't match)
+ switch (selector) {
+ case "startDeviceMotionUpdatesUsingReferenceFrame:":
+ case "startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:":
+ case "attitudeReferenceFrame":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ return base.Skip (type, method, selector);
+ }
+
+ protected override bool IsValidStruct (Type type, string structName)
+ {
+ switch (structName) {
+ // CIImage 'static MonoTouch.CoreImage.CIImage FromImageBuffer(MonoTouch.CoreVideo.CVPixelBuffer)' selector: imageWithCVPixelBuffer: == @12@0:4^{__CVBuffer=}
+ case "__CVBuffer":
+ return type.Name == "CVPixelBuffer" || type.Name == "CVImageBuffer";
+ }
+ return base.IsValidStruct (type, structName);
+ }
+
+ // only handle exception here (to return true) otherwise call base to deal with it
+ // `caller` is provided to make it easier to detect "special" cases
+ protected override bool Check (char encodedType, Type type)
+ {
+ // return an error if null (instead of throwing) so we can continue execution
+ if (type == null)
+ return false;
+
+ switch (encodedType) {
+ case 'c': // char, used for C# bool
+#if !XAMCORE_2_0
+ switch (type.FullName) {
+ // looks like it returns a bool even if documented as a void
+ // UIPrintInteractionController 'instance Void Present(Boolean, MonoTouch.UIKit.UIPrintInteractionCompletionHandler)' selector: presentAnimated:completionHandler:
+ // update: documentation (and header) mistake that Apple corrected (IIRC I filled that issue)
+ case "System.Void":
+ return CurrentType.Name == "UIPrintInteractionController";
+ }
+#endif
+ break;
+ // float (32 bits)
+ case 'f':
+ switch (type.FullName) {
+ // documented (web and header file) as NSInteger
+ // UIImageView 'instance Void set_AnimationRepeatCount(Int32)' selector: setAnimationRepeatCount: == v12@0:4f8
+ case "System.Int32":
+ return CurrentType.FullName == "MonoTouch.UIKit.UIImageView";
+ }
+ break;
+ case 'i':
+ switch (type.FullName) {
+ case "MonoTouch.EventKitUI.EKCalendarChooserSelectionStyle":
+ case "MonoTouch.EventKitUI.EKCalendarChooserDisplayStyle":
+ case "EventKitUI.EKCalendarChooserSelectionStyle":
+ case "EventKitUI.EKCalendarChooserDisplayStyle":
+ return (IntPtr.Size == 4) || !IsOSX11OrIOS9;
+ case "System.UInt32":
+ // numberOfTouchesRequired was signed before iOS6, unsigned since then
+ return true;
+ }
+ break;
+ // unsigned 32 bits
+ case 'I':
+ switch (type.FullName) {
+ case "System.Int32":
+ // sign-ness mis-binding, several of them (not critical)
+ // CBATTRequest 'instance Int32 get_Offset()' selector: offset == I8@0:4
+ return true;
+ }
+ break;
+ // unsigned 32 bits
+ case 'L':
+ switch (type.FullName) {
+ // sign-ness mis-binding (not critical) e.g.
+ // CAMediaTimingFunction 'instance Void GetControlPointAtIndex(Int32, IntPtr)' selector: getControlPointAtIndex:values: == v16@0:4L8[2f]12
+ case "System.Int32":
+ return true;
+ }
+ break;
+ // unsigned 64 bits
+ case 'Q':
+ switch (type.FullName) {
+ // sign-ness mis-binding (not critical) e.g.
+ // NSIncrementalStoreNode 'instance Int64 get_Version()' selector: version == Q8@0:4
+ case "System.Int64":
+ return true;
+ }
+ break;
+ }
+ return base.Check (encodedType, type);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/iOSApiTypoTest.cs b/tests/dont link/iOSApiTypoTest.cs
new file mode 100644
index 000000000000..40ee7cae415b
--- /dev/null
+++ b/tests/dont link/iOSApiTypoTest.cs
@@ -0,0 +1,55 @@
+using System;
+using NUnit.Framework;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+#else
+using MonoTouch;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#endif
+namespace TouchUnit.Bindings
+{
+ [TestFixture]
+ public class iOSApiTypoTest : ApiTypoTest
+ {
+#if !__WATCHOS__
+ UITextChecker checker = new UITextChecker ();
+#endif
+
+ [SetUp]
+ public void SetUp ()
+ {
+#if __WATCHOS__
+ Assert.Fail ("Need to find alternative for UITextChecker on WatchOS.");
+#else
+ // that's slow and there's no value to run it on devices as the API names
+ // being verified won't change from the simulator
+ if (Runtime.Arch == Arch.DEVICE)
+ Assert.Ignore ("Typos only detected on simulator");
+
+ // the dictionary used by iOS varies with versions and
+ // we don't want to maintain special cases for each version
+ var sdk = new Version (Constants.SdkVersion);
+ if (!UIDevice.CurrentDevice.CheckSystemVersion (sdk.Major, sdk.Minor))
+ Assert.Ignore ("Typos only verified using the latest SDK");
+#endif
+ }
+
+ public override string GetTypo (string txt)
+ {
+#if __WATCHOS__
+ return string.Empty;
+#else
+ var checkRange = new NSRange (0, txt.Length);
+ var typoRange = checker.RangeOfMisspelledWordInString (txt, checkRange, checkRange.Location, false, "en_US");
+ if (typoRange.Length == 0)
+ return String.Empty;
+ return txt.Substring ((int) typoRange.Location, (int) typoRange.Length);
+#endif
+ }
+ }
+}
diff --git a/tests/dont link/iOSApiWeakPropertyTest.cs b/tests/dont link/iOSApiWeakPropertyTest.cs
new file mode 100644
index 000000000000..dc64ea7825f7
--- /dev/null
+++ b/tests/dont link/iOSApiWeakPropertyTest.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Reflection;
+
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+
+using NUnit.Framework;
+
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSApiWeakPropertyTest : ApiWeakPropertyTest {
+
+ public iOSApiWeakPropertyTest ()
+ {
+ ContinueOnFailure = true;
+ }
+
+ protected override bool Skip (PropertyInfo property)
+ {
+ switch (property.DeclaringType.Name) {
+ // WeakVideoGravity is an NSString that we could/should provide a better binding (e.g. enum)
+ case "AVPlayerViewController":
+ return property.Name == "WeakVideoGravity";
+ // CATextLayer.WeakFont is done correctly by hand
+ case "CATextLayer":
+ return property.Name == "WeakFont";
+ // NSAttributedStringDocumentAttributes is a DictionaryContainer that expose some Weak* NSDictionary
+ case "NSAttributedStringDocumentAttributes":
+ return property.Name == "WeakDocumentType" || property.Name == "WeakDefaultAttributes";
+ // UIFontAttributes is a DictionaryContainer that expose a Weak* NSDictionary
+ case "UIFontAttributes":
+ return property.Name == "WeakFeatureSettings";
+ // UIStringAttributes is a DictionaryContainer that expose a Weak* NSString
+ case "UIStringAttributes":
+ return property.Name == "WeakTextEffect";
+#if !XAMCORE_3_0
+ // #37451 - setter does not exists but we have to keep it for binary compatibility
+ // OTOH we can't give it a selector (private API) even if we suspect Apple is mostly running `strings` on executable
+ case "IUIViewControllerPreviewing":
+ return property.Name == "WeakDelegate";
+ case "UIViewControllerPreviewingWrapper":
+ return property.Name == "WeakDelegate";
+#endif
+ }
+ return base.Skip (property);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dont link/iOSCoreImageFiltersTest.cs b/tests/dont link/iOSCoreImageFiltersTest.cs
new file mode 100644
index 000000000000..d0a54d2ace4f
--- /dev/null
+++ b/tests/dont link/iOSCoreImageFiltersTest.cs
@@ -0,0 +1,37 @@
+//
+// Test the generated API for all iOS CoreImage filters
+//
+// Authors:
+// Sebastien Pouliot
+// Alex Soto
+//
+// Copyright 2012-2013 Xamarin Inc. All rights reserved.
+//
+
+#if !__WATCHOS__
+
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using CoreImage;
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.CoreImage;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class iOSCoreImageFiltersTest : ApiCoreImageFiltersTest {
+
+
+ }
+}
+#endif // !__WATCHOS__
diff --git a/tests/dont link/sample_sorenson.mov b/tests/dont link/sample_sorenson.mov
new file mode 100644
index 000000000000..92aa0176adeb
Binary files /dev/null and b/tests/dont link/sample_sorenson.mov differ
diff --git a/tests/dontlink-mac/.gitignore b/tests/dontlink-mac/.gitignore
new file mode 100644
index 000000000000..e82b2790c20e
--- /dev/null
+++ b/tests/dontlink-mac/.gitignore
@@ -0,0 +1,4 @@
+TestResult*xml
+dontlink.sln
+tests.xml
+build
diff --git a/tests/dontlink-mac/Info.plist b/tests/dontlink-mac/Info.plist
new file mode 100644
index 000000000000..7de8f9e319a1
--- /dev/null
+++ b/tests/dontlink-mac/Info.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ CFBundleDisplayName
+ apitest
+ CFBundleIdentifier
+ com.xamarin.apitest
+ CFBundleName
+ apitest
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 10.7
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/tests/dontlink-mac/Mac.cs b/tests/dontlink-mac/Mac.cs
new file mode 100644
index 000000000000..3c8845b011f6
--- /dev/null
+++ b/tests/dontlink-mac/Mac.cs
@@ -0,0 +1,40 @@
+//
+// Mac-specific Helpers
+//
+// Authors:
+// Sebastien Pouliot
+// Aaron Bockover
+//
+// Copyright 2012-2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+#if XAMCORE_2_0
+using ObjCRuntime;
+#else
+using MonoMac.ObjCRuntime;
+#endif
+
+using TouchUnit.Bindings;
+
+namespace MonoMacFixtures {
+
+ public static class Mac {
+ public static readonly Version Version_10_7 = new Version (10, 7);
+ public static readonly Version Version_10_8 = new Version (10, 8);
+ public static readonly Version Version_10_9 = new Version (10, 9);
+ public static readonly Version Version_10_10 = new Version (10, 10);
+ public static readonly Version Version_10_11 = new Version (10, 11);
+
+ static PlatformInfo host => PlatformInfo.Host;
+
+ public static bool CheckSystemVersion (int major, int minor) => host.Version >= new Version (major, minor);
+ public static bool Is32BitMavericks => host.IsArch32 && IsAtLeast (Version_10_9);
+ public static bool IsYosemiteOrHigher => IsAtLeast (Version_10_10);
+ public static bool IsElCapitanOrHigher => IsAtLeast (Version_10_11);
+ public static bool IsAtLeast (int major, int minor) => IsAtLeast (new Version (major, minor));
+ public static bool IsAtLeast (Version version) => host.IsMac && host.Version >= version;
+ }
+}
diff --git a/tests/dontlink-mac/MacApiCtorInitTest.cs b/tests/dontlink-mac/MacApiCtorInitTest.cs
new file mode 100644
index 000000000000..9f474d846148
--- /dev/null
+++ b/tests/dontlink-mac/MacApiCtorInitTest.cs
@@ -0,0 +1,245 @@
+//
+// Mac-specific `init*` selectors validations
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013,2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoMac.Foundation;
+#endif
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ public class MacApiCtorInitTest : ApiCtorInitTest {
+
+ public MacApiCtorInitTest ()
+ {
+ //LogProgress = true;
+ ContinueOnFailure = true;
+ }
+
+ protected override bool Skip (Attribute attr)
+ {
+ return base.Skip (attr);
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.FullName) {
+ // These should be DisableDefaultCtor but can't due to backward compat
+ case "MonoMac.EventKit.EKParticipant":
+ case "EventKit.EKParticipant":
+ case "XamCore.CoreImage.CISampler":
+ case "CoreImage.CISampler":
+ return true;
+ // OSX 10.8+
+ case "MonoMac.AppKit.NSSharingService":
+ case "AppKit.NSSharingService":
+ case "MonoMac.AppKit.NSSharingServicePicker":
+ case "AppKit.NSSharingServicePicker":
+ case "MonoMac.Foundation.NSUserNotification":
+ case "Foundation.NSUserNotification":
+ case "MonoMac.Foundation.NSUserNotificationCenter":
+ case "Foundation.NSUserNotificationCenter":
+ case "MonoMac.AVFoundation.AVPlayerItemVideoOutput":
+ case "AVFoundation.AVPlayerItemVideoOutput":
+ case "MonoMac.Foundation.NSUuid":
+ case "Foundation.NSUuid":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ // Native exception coming from [NSWindow init] which calls
+ // [NSWindow initWithContentRect:styleMask:backing:defer]
+ case "MonoMac.AppKit.NSWindow":
+ case "AppKit.NSWindow":
+ return true;
+#if !XAMCORE_2_0
+ case "MonoMac.AppKit.NSToolbar": // mono[10518:626783] *** -[__NSDictionaryM removeObjectForKey:]: key cannot be nil
+ case "MonoMac.SceneKit.SCNRenderer": // -[SCNRenderer init]: unrecognized selector sent to instance 0x7c6446c0
+ case "MonoMac.SceneKit.SCNLookAtConstraint":
+ return true;
+#endif
+ case "MonoMac.Foundation.NSUrlSession":
+ case "Foundation.NSUrlSession":
+ case "MonoMac.Foundation.NSUrlSessionTask":
+ case "Foundation.NSUrlSessionTask":
+ case "MonoMac.Foundation.NSUrlSessionDataTask":
+ case "Foundation.NSUrlSessionDataTask":
+ case "MonoMac.Foundation.NSUrlSessionUploadTask":
+ case "Foundation.NSUrlSessionUploadTask":
+ case "MonoMac.Foundation.NSUrlSessionDownloadTask":
+ case "Foundation.NSUrlSessionDownloadTask":
+ case "MonoMac.Foundation.NSUrlSessionConfiguration":
+ case "Foundation.NSUrlSessionConfiguration":
+ // These types were introduced as 64-bit only in Mavericks, and 32+64bits in Yosemite. We can't
+ // express that with our AvailabilityAttribute, we set it as available (for all architectures, since
+ // we can't distinguish them) starting with Mavericks.
+ if (Mac.Is32BitMavericks)
+ return true;
+ break;
+
+ case "GLKit.GLKSkyboxEffect":
+ // Crashes inside libGL.dylib, most likely because something hasn't been initialized yet, because
+ // I can reproduce in an Xcode project if I put [[GLKSkyboxEffect alloc] init]; in main, but it doesn't
+ // crash in applicationDidFinishLaunching.
+ //
+ // frame #0: 0x00007fff8d570db1 libGL.dylib`glGetError + 13
+ // frame #1: 0x0000000100025542 GLKit`-[GLKEffect initWithPropertyArray:] + 1142
+ // frame #2: 0x0000000100022c2d GLKit`-[GLKSkyboxEffect init] + 493
+ //
+ if (IntPtr.Size == 8)
+ return true;
+ break;
+
+#if !XAMCORE_3_0
+ case "SpriteKit.SKView":
+ // Causes a crash later. Filed as radar://18440271.
+ // Apple said they won't fix this ('init' isn't a designated initializer)
+ if (IntPtr.Size == 8)
+ return true;
+ break;
+#endif
+
+ case "MonoMac.AppKit.NSSpeechRecognizer":
+ case "AppKit.NSSpeechRecognizer":
+ // Makes OSX put up "a download is required for speech recognition" dialog.
+ return true;
+
+ case "MonoMac.Foundation.NSUserActivity":
+ case "Foundation.NSUserActivity":
+ // Crashes by default:
+ // Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Caller did not provide an activityType, and this process does not have a NSUserActivityTypes in its Info.plist.
+ // but since it looks like the constructor is usable with the proper Info.plist, we can't remove it.
+ return true;
+ }
+
+ switch (type.Namespace) {
+ // OSX 10.8+
+ case "MonoMac.Accounts":
+ case "Accounts":
+ case "MonoMac.GameKit":
+ case "GameKit":
+ case "MonoMac.Social":
+ case "Social":
+ case "MonoMac.StoreKit":
+ case "StoreKit":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ case "SceneKit":
+ case "MonoMac.SceneKit":
+ if (!Mac.CheckSystemVersion (10, 8) || IntPtr.Size != 8)
+ return true;
+ break;
+ }
+
+ return base.Skip (type);
+ }
+
+ protected override void CheckNSObjectProtocol (NSObject obj)
+ {
+ switch (obj.GetType ().Name) {
+ case "NSString":
+ // according to bots `isKindOf (null)` returns true before Yosemite
+ break;
+ case "SBObject":
+ // *** NSForwarding: warning: object 0x77a49a0 of class '__NSMessageBuilder' does not implement doesNotRecognizeSelector: -- abort
+ break;
+ default:
+ base.CheckNSObjectProtocol (obj);
+ break;
+ }
+ }
+
+ protected override void CheckToString (NSObject obj)
+ {
+ switch (obj.GetType ().FullName) {
+ // native crash calling MonoMac.Foundation.NSObject.get_Description ()
+ case "WebKit.WKNavigationAction":
+ case "WebKit.WKFrameInfo": // EXC_BAD_ACCESS (code=1, address=0x0)
+ case "MonoMac.Foundation.NSUrlConnection":
+ case "Foundation.NSUrlConnection":
+ case "MonoMac.AppKit.NSLayoutConstraint": // Unable to create description in descriptionForLayoutAttribute_layoutItem_coefficient. Something is nil
+ case "AppKit.NSLayoutConstraint":
+ case "MonoMac.AVFoundation.AVPlayerItemTrack":
+ case "AVFoundation.AVPlayerItemTrack":
+ // 10.8
+ case "MonoMac.AVFoundation.AVComposition":
+ case "AVFoundation.AVComposition":
+ case "MonoMac.GameKit.GKPlayer": // Crashing on 10.8.3 from the Apple beta channel for abock (on 2013-01-30)
+ case "GameKit.GKPlayer":
+ case "MonoMac.AVFoundation.AVAssetResourceLoadingRequest": // Crashing on 10.9.1 for abock (2014-01-13)
+ case "AVFoundation.AVAssetResourceLoadingRequest":
+ case "MonoMac.AVFoundation.AVAssetResourceLoadingDataRequest": // Crashes on 10.9.3 for chamons (constructor found in AVCompat)
+ case "AVFoundation.AVAssetResourceLoadingDataRequest":
+ case "MonoMac.AVFoundation.AVCaptureDeviceInputSource": // Crashes on 10.9.5
+ case "AVFoundation.AVCaptureDeviceInputSource":
+ break;
+ default:
+ base.CheckToString (obj);
+ break;
+ }
+ }
+
+ static List do_not_dispose = new List ();
+
+ protected override void Dispose (NSObject obj, Type type)
+ {
+ switch (type.FullName) {
+ // FIXME: those crash the application when Dispose is called
+ case "MonoMac.JavaScriptCore.JSManagedValue":
+ case "JavaScriptCore.JSManagedValue":
+ // JSManagedValue crashes in Yosemite (b7), but not Mavericks.
+ if (!Mac.CheckSystemVersion (10, 10))
+ goto default;
+ goto case "MonoMac.ImageKit.IKScannerDeviceView"; // fallthrough
+ case "MonoMac.ImageKit.IKScannerDeviceView": // 19835
+ case "ImageKit.IKScannerDeviceView":
+ case "MonoMac.AppKit.NSFontPanel": // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x11491cc00 of class NSButton was deallocated while key value observers were still registered with it.
+ case "AppKit.NSFontPanel":
+ case "MonoMac.AVFoundation.AVAudioRecorder": // same on iOS
+ case "AVFoundation.AVAudioRecorder":
+ case "MonoMac.Foundation.NSUrlConnection":
+ case "Foundation.NSUrlConnection":
+ // 10.8:
+ case "MonoMac.Accounts.ACAccount": // maybe the default .ctor is not allowed ?
+ case "Accounts.ACAccount":
+ case "MonoMac.Accounts.ACAccountCredential":
+ case "Accounts.ACAccountCredential":
+ case "MonoMac.Accounts.ACAccountStore":
+ case "Accounts.ACAccountStore":
+ case "MonoMac.Accounts.ACAccountType":
+ case "Accounts.ACAccountType":
+ case "MonoMac.CoreData.NSPersistentStoreCoordinator":
+ case "CoreData.NSPersistentStoreCoordinator":
+ do_not_dispose.Add (obj);
+ break;
+ // 10.11
+ case "MonoMac.CoreImage.CIImageAccumulator":
+ case "CoreImage.CIImageAccumulator":
+ case "WebKit.WKNavigation":
+ // crashes on El Capitan (b2) but not before
+ if (!Mac.CheckSystemVersion (10, 11))
+ goto default;
+ do_not_dispose.Add (obj);
+ break;
+ default:
+ base.Dispose (obj, type);
+ break;
+ }
+ }
+ }
+}
diff --git a/tests/dontlink-mac/MacApiFieldTest.cs b/tests/dontlink-mac/MacApiFieldTest.cs
new file mode 100644
index 000000000000..da552d7a12cb
--- /dev/null
+++ b/tests/dontlink-mac/MacApiFieldTest.cs
@@ -0,0 +1,233 @@
+//
+// Mac specific fields validator
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class MacApiFieldTest : ApiFieldTest {
+
+ public MacApiFieldTest ()
+ {
+ ContinueOnFailure = true;
+ }
+
+ static bool IsUnified {
+ get
+ {
+ return AppDomain.CurrentDomain.GetAssemblies().Any(x => x.FullName.Contains("Xamarin.Mac"));
+ }
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.FullName) {
+ // OS X 10.8 +
+ case "MonoMac.AppKit.NSSharingService":
+ case "AppKit.NSSharingService":
+ case "MonoMac.Foundation.NSUserNotification":
+ case "Foundation.NSUserNotification":
+ return !Mac.CheckSystemVersion (10, 8);
+ }
+
+ switch (type.Namespace) {
+ // OSX 10.8+
+ case "MonoMac.Accounts":
+ case "Accounts":
+ case "MonoMac.GameKit":
+ case "GameKit":
+ case "MonoMac.Social":
+ case "Social":
+ return !Mac.CheckSystemVersion (10, 8);
+ case "SceneKit":
+ case "MonoMac.SceneKit":
+ return !Mac.CheckSystemVersion (10, 8) || IntPtr.Size != 8;
+ default:
+ return false;
+ }
+ }
+
+ protected override bool Skip (PropertyInfo p)
+ {
+ switch (p.DeclaringType.Name) {
+ case "NSUrlSessionDownloadDelegate":
+ switch (p.Name) {
+ case "TaskResumeDataKey":
+ // This field was introduced as 64-bit only in Mavericks, and 32+64bits in Yosemite. We can't
+ // express that with our AvailabilityAttribute, we set it as available (for all architectures, since
+ // we can't distinguish them) starting with Mavericks.
+ if (Mac.Is32BitMavericks)
+ return true;
+ break;
+ }
+ break;
+ }
+
+ switch (p.Name) {
+ // NSTableView
+ case "RowViewKey":
+ return true;
+ // NSBitmapImageRep
+ case "CompressionMethod":
+ case "CompressionFactor":
+ case "DitherTransparency":
+ return true;
+ // CIImage 10.8+
+ case "AutoAdjustFeaturesKey": // kCIImageAutoAdjustFeatures - documented in 10.8
+ case "AutoAdjustRedEyeKey":
+ case "AutoAdjustEnhanceKey":
+ case "CIImagePropertiesKey":
+ return true;
+ // CIImage
+ case "CIImageColorSpaceKey":
+ return true; // returns null but documented prior to 10.8
+ // CLLocation 10.8+
+ case "ErrorUserInfoAlternateRegionKey": // kCLErrorUserInfoAlternateRegionKey also returns null on iOS
+ return true;
+ // NSUrl 10.8+
+ case "PathKey":
+ return !Mac.CheckSystemVersion (10, 8);
+ // AVMediaCharacteristic 10.8+
+ case "IsMainProgramContent":
+ case "IsAuxiliaryContent":
+ case "ContainsOnlyForcedSubtitles":
+ case "TranscribesSpokenDialogForAccessibility":
+ case "DescribesMusicAndSoundForAccessibility":
+ case "DescribesVideoForAccessibility":
+ return !Mac.CheckSystemVersion (10, 8);
+ // AVVideo 10.8+
+ case "ProfileLevelH264Main32":
+ return !Mac.CheckSystemVersion (10, 8);
+ // AVMetadata 10.8+
+ case "QuickTimeUserDataKeyTaggedCharacteristic":
+ return !Mac.CheckSystemVersion (10, 8);
+ // CIDetector
+ case "TypeFace": // CIDetectorTypeFace - documented as available in 10.7
+ case "Accuracy": // CIDetectorAccuracy 10.7
+ case "AccuracyLow": // CIDetectorAccuracyLow 10.7
+ case "AccuracyHigh": // CIDetectorAccuracyHigh 10.7
+ return true;
+ // CIDetector
+ case "ImageOrientation": // documented in 10.8
+ case "Tracking":
+ case "MinFeatureSize":
+ return true;
+ // CGImageProperties - all new (10.7) values are missing (from pre-6 iOS too iirc)
+ case "ExifCameraOwnerName": // kCGImagePropertyExifCameraOwnerName
+ case "ExifBodySerialNumber": // kCGImagePropertyExifBodySerialNumber
+ case "ExifLensSpecification": // kCGImagePropertyExifLensSpecification
+ case "ExifLensMake": // kCGImagePropertyExifLensMake
+ case "ExifLensModel": // kCGImagePropertyExifLensModel
+ case "ExifLensSerialNumber": // kCGImagePropertyExifLensSerialNumber
+ return true;
+ // ACErrorDomain is _listed_ in the 10.8 Accounts Changes but like iOS it's not documented anywhere else (and does not seems to exists)
+ case "ErrorDomain":
+ // ACAccountStoreDidChangeNotification - documented in 10.8
+ case "ChangeNotification":
+ // ACAccountType - documented in 10.8
+ case "Twitter": // ACAccountTypeIdentifierTwitter
+ case "SinaWeibo":
+ case "Facebook":
+ case "AppId": // ACFacebookAppIdKey
+ case "Permissions": // ACFacebookPermissionsKey
+ case "Audience": // *** NOT documented in 10.8 - but part of our API enhancement
+ case "Everyone": // ^ MonoMac.Accounts.ACFacebookAudienceValue.Everyone
+ case "Friends": // ^ MonoMac.Accounts.ACFacebookAudienceValue.Friends
+ case "OnlyMe": // ^ MonoMac.Accounts.ACFacebookAudienceValue.OnlyMe
+ return true;
+ // MonoMac.CoreServices.CFHTTPMessage - document in 10.9 but returns null
+ case "_AuthenticationSchemeOAuth1":
+ return true;
+ default:
+ return base.Skip (p);
+ }
+ }
+
+ protected override bool Skip (string constantName)
+ {
+ switch (constantName) {
+ // Only there for API compat
+ case "kSecUseNoAuthenticationUI":
+ case "kSecUseOperationPrompt":
+ return !IsUnified;
+ // MonoMac.CoreServices.CFHTTPMessage - document in 10.9 but returns null
+ case "kCFHTTPAuthenticationSchemeOAuth1":
+ return true;
+ // kCLErrorUserInfoAlternateRegionKey also returns null on iOS
+ case "kCLErrorUserInfoAlternateRegionKey":
+ return true;
+ case "NSURLSessionTransferSizeUnknown":
+ case "NSURLSessionDownloadTaskResumeData":
+ if (Mac.Is32BitMavericks)
+ return true;
+ goto default;
+ default:
+ return base.Skip (constantName);
+ }
+ }
+
+ protected override string FindLibrary (string libraryName, bool requiresFullPath = false)
+ {
+ switch (libraryName) {
+ case "CFNetwork":
+ if (Mac.IsAtLeast (10,8))
+ break;
+ return "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/CFNetwork";
+ case "CoreText":
+ case "CoreGraphics":
+ if (Mac.IsAtLeast (10,8))
+ break;
+ return string.Format ("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/{0}.framework/{0}", libraryName);
+ case "ImageIO":
+ if (Mac.IsAtLeast (10,9))
+ break;
+ return "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/ImageIO";
+ case "CoreImage":
+ // generated code uses QuartzCore correctly - even if the [Field] property is wrong
+ libraryName = "QuartzCore";
+ break;
+ case "QuartzComposer":
+ case "PdfKit":
+ case "ImageKit":
+ // generated code uses Quartz correctly - even if the [Field] property is wrong
+ libraryName = "Quartz";
+ break;
+ case "CoreBluetooth":
+ if (Mac.IsYosemiteOrHigher) {
+ // CoreBluetooth is in /System/Library/Frameworks/CoreBluetooth.framework starting with Yosemite.
+ break;
+ }
+
+ // CoreBluetooth is inside IOBluetooth.framework in earlier OSXs
+ return "/System/Library/Frameworks/IOBluetooth.framework/Versions/A/Frameworks/CoreBluetooth.framework/CoreBluetooth";
+ case "SearchKit":
+ return "/System/Library/Frameworks/CoreServices.framework/Frameworks/SearchKit.framework/SearchKit";
+ }
+
+ return base.FindLibrary (libraryName, requiresFullPath);
+ }
+ }
+}
diff --git a/tests/dontlink-mac/MacApiPInvokeTest.cs b/tests/dontlink-mac/MacApiPInvokeTest.cs
new file mode 100644
index 000000000000..df2399fdc59b
--- /dev/null
+++ b/tests/dontlink-mac/MacApiPInvokeTest.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Linq;
+using System.IO;
+using System.Reflection;
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class MacApiPInvokeTest : ApiPInvokeTest {
+ protected override bool SkipLibrary (string libraryName)
+ {
+ switch (libraryName){
+ case "/System/Library/Frameworks/OpenGL.framework/OpenGL":
+ return true;
+ }
+ return base.SkipLibrary (libraryName);
+ }
+
+ static bool IsUnified {
+ get
+ {
+ return AppDomain.CurrentDomain.GetAssemblies().Any(x => x.FullName.Contains("Xamarin.Mac"));
+ }
+ }
+
+ protected override bool Skip (Type type)
+ {
+ string typeName = type.ToString ();
+ bool is32Bit = IntPtr.Size == 4;
+ if (is32Bit && typeName.StartsWith ("MapKit")) // MapKit is 64-bit only
+ return true;
+
+ switch (type.Namespace) {
+ case "SceneKit":
+ case "MonoMac.SceneKit":
+ if (is32Bit)
+ return true;
+ break;
+ }
+
+ switch (typeName) {
+ case "MonoMac.GameController.GCExtendedGamepadSnapshot": // These next 4 are in the compat API, even if they don't work.
+ case "MonoMac.GameController.GCGamepadSnapshot":
+ case "MonoMac.GameController.GCExtendedGamepadSnapShotDataV100":
+ case "MonoMac.GameController.GCGamepadSnapShotDataV100":
+ return !IsUnified;
+ case "GameController.GCGamepadSnapShotDataV100": // These are 64-bit only
+ case "GameController.GCExtendedGamepadSnapShotDataV100":
+ return is32Bit;
+ case "MonoMac.AudioToolbox.AudioSession": // These are iOS APIs that were mistakenly pulled into OSX. Removed in unified but not classic
+ case "MonoMac.AudioUnit.AudioUnitUtils":
+ return !IsUnified; // If these are in unified, don't skip, we want to scream
+ }
+
+ return base.Skip(type);
+ }
+
+ protected override bool Skip (string symbolName)
+ {
+ switch (symbolName) {
+ case "SKTerminateForInvalidReceipt": // Only there for API compat
+ return !IsUnified;
+ }
+ return false;
+ }
+
+ protected override bool SkipAssembly (Assembly a)
+ {
+ // too many things are missing from XM 32bits bindings
+ // and the BCL is identical for 64 bits (no need to test it 3 times)
+// return IntPtr.Size == 4;
+ return true; // skip everything until fixed
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/dontlink-mac/MacApiProtocolTest.cs b/tests/dontlink-mac/MacApiProtocolTest.cs
new file mode 100644
index 000000000000..a4125d0d1443
--- /dev/null
+++ b/tests/dontlink-mac/MacApiProtocolTest.cs
@@ -0,0 +1,176 @@
+//
+// Test the generated API for common protocol support
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc.
+//
+
+using System;
+
+#if XAMCORE_2_0
+using Foundation;
+using AppKit;
+using CoreImage;
+#else
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+using MonoMac.CoreImage;
+#endif
+
+using NUnit.Framework;
+
+using TouchUnit.Bindings;
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class MonoMacFixtures : ApiProtocolTest {
+
+ protected override bool Skip (Type type, string protocolName)
+ {
+ switch (protocolName) {
+ case "NSSecureCoding":
+ switch (type.Name) {
+ case "NSCachedImageRep": // Not declared in header file
+ case "NSCIImageRep":
+ case "NSCustomImageRep":
+ case "NSEPSImageRep":
+ case "NSBitmapImageRep":
+ case "NSImageRep":
+ case "NSPdfImageRep":
+ case "AVAssetTrackSegment": // Not declared in header file
+ case "AVComposition": // Not declared in header file
+ case "AVMutableComposition": // Not declared in header file
+ case "AVCompositionTrackSegment": // Not declared in header file
+ case "MKMapSnapshotOptions": // Not declared in header file
+ case "NSTextTab": // Not declared in header file
+ return true;
+ default:
+ // CIFilter started implementing NSSecureCoding in 10.11
+ if (!Mac.CheckSystemVersion (10, 11) && (type == typeof(CIFilter) || type.IsSubclassOf (typeof(CIFilter))))
+ return true;
+ break;
+ }
+ break;
+ case "NSCopying":
+ switch (type.Name) {
+ case "DomNodeFilter": // Not declared in header file
+ case "MKDirectionsRequest": // Not declared in header file
+ case "EKObject": // Not declared in header file
+ case "EKCalendarItem": // Not declared in header file
+ case "EKSource": // Not declared in header file
+ case "EKCalendar": // Not declared in header file
+ case "EKEvent": // Not declared in header file
+ case "EKReminder": // Not declared in header file
+ case "ACAccount": // Not declared in header file
+ return true;
+ }
+ break;
+ case "NSMutableCopying":
+ switch (type.Name) {
+ case "EKObject": // Not declared in header file
+ case "EKCalendarItem": // Not declared in header file
+ case "EKSource": // Not declared in header file
+ case "EKStructuredLocation": // Not declared in header file
+ case "EKAlarm": // Not declared in header file
+ case "EKCalendar": // Not declared in header file
+ case "EKEvent": // Not declared in header file
+ case "EKParticipant": // Not declared in header file
+ case "EKRecurrenceRule": // Not declared in header file
+ case "EKReminder": // Not declared in header file
+ return true;
+ }
+ break;
+ case "NSCoding":
+ switch (type.Name) {
+ case "EKObject": // Not declared in header file
+ case "EKCalendarItem": // Not declared in header file
+ case "EKSource": // Not declared in header file
+ case "EKStructuredLocation": // Not declared in header file
+ case "EKAlarm": // Not declared in header file
+ case "EKCalendar": // Not declared in header file
+ case "EKEvent": // Not declared in header file
+ case "EKParticipant": // Not declared in header file
+ case "EKRecurrenceRule": // Not declared in header file
+ case "EKReminder": // Not declared in header file
+ case "AVAssetTrackSegment": // Not declared in header file
+ case "AVComposition": // Not declared in header file
+ case "AVMutableComposition": // Not declared in header file
+ case "AVCompositionTrackSegment": // Not declared in header file
+ case "MKMapSnapshotOptions": // Not declared in header file
+ return true;
+ }
+ break;
+ case "NSWindowRestoration":
+ switch (type.Name) {
+ case "NSDocumentController":
+ // There's a category that implements the NSWindowRestoration protocol for NSDocumentController,
+ // but that apparently doesn't make conformsToProtocol: return true.
+ // '@interface NSDocumentController (NSWindowRestoration) '
+ return true;
+ }
+ break;
+ case "NSUserInterfaceItemIdentification":
+ // NSViewController started implementing NSUserInterfaceItemIdentification in 10.10
+ if (!Mac.CheckSystemVersion (10, 10) && (type == typeof(NSViewController) || type.IsSubclassOf (typeof (NSViewController))))
+ return true;
+
+ break;
+ case "NSMenuDelegate":
+ switch (type.Name) {
+ case "PdfView":
+ if (!Mac.CheckSystemVersion (10, 10))
+ return true;
+ break;
+ }
+ break;
+ case "NSTextFinderClient": // Not listed in header, nor conformsToProtocol, but works in sample. But it just repondsToSelectors
+ if (type.Name == "NSTextView")
+ return true;
+ break;
+#if !XAMCORE_4_0
+ case "NSDraggingInfo":
+ return true; // We have to keep the type to maintain backwards compatibility.
+#endif
+ }
+
+ switch (type.Name) {
+#if !XAMCORE_3_0
+ case "NSRemoteSavePanel":
+ case "NSRemoteOpenPanel":
+ return true; // These two classes don't show up in any documentation.
+#endif
+ }
+
+ switch (type.Namespace) {
+ case "MonoMac.SceneKit":
+ case "SceneKit":
+ return IntPtr.Size == 4; // 64bits should be fine
+ }
+
+ return base.Skip (type, protocolName);
+ }
+
+ [Test]
+ public override void SecureCoding ()
+ {
+ if (!Mac.CheckSystemVersion (10, 8))
+ return;
+
+ base.SecureCoding ();
+ }
+
+ [Test]
+ public override void SupportsSecureCoding ()
+ {
+ if (!Mac.CheckSystemVersion (10,8))
+ return;
+
+ base.SupportsSecureCoding ();
+ }
+ }
+}
diff --git a/tests/dontlink-mac/MacApiSelectorTest.cs b/tests/dontlink-mac/MacApiSelectorTest.cs
new file mode 100644
index 000000000000..9d5d361c1e1c
--- /dev/null
+++ b/tests/dontlink-mac/MacApiSelectorTest.cs
@@ -0,0 +1,819 @@
+//
+// Mac specific selector validators
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ public class MacApiSelectorTest : CoreSelectorTest {
+
+ static MacApiSelectorTest ()
+ {
+ Runtime.RegisterAssembly (typeof (NSObject).Assembly);
+ }
+
+ public MacApiSelectorTest ()
+ {
+ //LogProgress = true; Don't uncomment this anymore, export API_TEST_LOG_PROGRESS=1
+ ContinueOnFailure = true;
+ }
+
+ protected override bool Skip (Type type)
+ {
+ switch (type.FullName) {
+ case "MonoMac.CIFilter.CIMaskedVariableBlur": // Appears to be missing from 10.11, not documented
+ case "CIFilter.CIMaskedVariableBlur":
+ if (Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ case "MonoMac.Foundation.NSUrlSession":
+ case "Foundation.NSUrlSession":
+ case "MonoMac.Foundation.NSUrlSessionTask":
+ case "Foundation.NSUrlSessionTask":
+ case "MonoMac.Foundation.NSUrlSessionDataTask":
+ case "Foundation.NSUrlSessionDataTask":
+ case "MonoMac.Foundation.NSUrlSessionUploadTask":
+ case "Foundation.NSUrlSessionUploadTask":
+ case "MonoMac.Foundation.NSUrlSessionDownloadTask":
+ case "Foundation.NSUrlSessionDownloadTask":
+ case "MonoMac.Foundation.NSUrlSessionConfiguration":
+ case "Foundation.NSUrlSessionConfiguration":
+ // These classes are available in 32-bit Yosemite, or 32+64bit Mavericks.
+ if (IntPtr.Size == 4 && !Mac.CheckSystemVersion (10, 10))
+ return true;
+ break;
+ case "MonoMac.AppKit.NSSharingService":
+ case "AppKit.NSSharingService":
+ case "MonoMac.AppKit.NSSharingServicePicker":
+ case "AppKit.NSSharingServicePicker":
+ case "MonoMac.Foundation.NSByteCountFormatter":
+ case "Foundation.NSByteCountFormatter":
+ case "MonoMac.Foundation.NSUserNotification":
+ case "Foundation.NSUserNotification":
+ case "MonoMac.Foundation.NSUserNotificationCenter":
+ case "Foundation.NSUserNotificationCenter":
+ case "MonoMac.AVFoundation.AVPlayerItemOutput":
+ case "AVFoundation.AVPlayerItemOutput":
+ case "MonoMac.AVFoundation.AVPlayerItemVideoOutput":
+ case "AVFoundation.AVPlayerItemVideoOutput":
+ case "MonoMac.Foundation.NSUuid":
+ case "Foundation.NSUuid":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ }
+
+ switch (type.Namespace) {
+ // OSX 10.8+
+ case "MonoMac.Accounts":
+ case "Accounts":
+ case "MonoMac.GameKit":
+ case "GameKit":
+ case "MonoMac.Social":
+ case "Social":
+ case "MonoMac.StoreKit":
+ case "StoreKit":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ case "SceneKit":
+ case "MonoMac.SceneKit":
+ if (!Mac.CheckSystemVersion (10, 8) || IntPtr.Size != 8)
+ return true;
+ break;
+ // not installed by default
+ case "MonoMac.Growl":
+ case "Growl":
+ return true;
+ }
+
+ return base.Skip (type);
+ }
+
+ protected override bool Skip (Type type, string selectorName)
+ {
+ switch (selectorName) {
+#if !XAMCORE_4_0
+ case "xamarinselector:removed:":
+ return true;
+#endif
+#if !XAMCORE_3_0
+ case "initWithPasteboardPropertyList:ofType:":
+ // This is a broken binding, but it's an abstract protocol
+ // method, so there's no way to remove it without breaking
+ // compat.
+ return true;
+#endif
+ case "waitUntilExit":
+ // category, NSTask won't respond -> @interface NSTask (NSTaskConveniences)
+ if (type.Name == "NSTask")
+ return true;
+ break;
+ case "readInBackgroundAndNotifyForModes:":
+ case "readInBackgroundAndNotify":
+ case "readToEndOfFileInBackgroundAndNotifyForModes:":
+ case "readToEndOfFileInBackgroundAndNotify":
+ case "acceptConnectionInBackgroundAndNotifyForModes:":
+ case "acceptConnectionInBackgroundAndNotify":
+ case "waitForDataInBackgroundAndNotifyForModes:":
+ case "waitForDataInBackgroundAndNotify":
+ // category, NSFileHandle won't respond -> @interface NSFileHandle (NSFileHandleAsynchronousAccess)
+ if (type.Name == "NSFileHandle")
+ return true;
+ break;
+ // initWithPlayerIDs: works (valid handle) and is documented - but does not respond when queried
+ case "initWithPlayerIDs:":
+ if (type.Name == "GKLeaderboard")
+ return true;
+ break;
+ // some types had NSCopying added after they were first introduced
+ case "copyWithZone:":
+ if (type.Name == "CBPeripheral" && !Mac.CheckSystemVersion (10, 9))
+ return true;
+ break;
+ case "readingOptionsForType:pasteboard:":
+ case "writingOptionsForType:pasteboard:":
+ return true; // Optional selectors on NSPasteboardReading/NSPasteboardWriting
+ }
+
+ switch (type.Namespace) {
+ // Notifications seems to follow a pattern were selectors are routed to an internal concrete type
+ case "MonoMac.Foundation":
+ case "Foundation":
+ switch (type.Name) {
+ // looks like it's routed to (private) NSConcreteUserNotificationCenter
+ case "NSUserNotificationCenter":
+ switch (selectorName) {
+ case "delegate":
+ case "setDelegate:":
+ case "scheduledNotifications":
+ case "setScheduledNotifications:":
+ case "deliveredNotifications":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) NSConcreteUserNotification
+ case "NSUserNotification":
+ switch (selectorName) {
+ case "title":
+ case "setTitle:":
+ case "subtitle":
+ case "setSubtitle:":
+ case "informativeText":
+ case "setInformativeText:":
+ case "actionButtonTitle":
+ case "setActionButtonTitle:":
+ case "userInfo":
+ case "setUserInfo:":
+ case "deliveryDate":
+ case "setDeliveryDate:":
+ case "deliveryTimeZone":
+ case "setDeliveryTimeZone:":
+ case "deliveryRepeatInterval":
+ case "setDeliveryRepeatInterval:":
+ case "actualDeliveryDate":
+ case "isPresented":
+ case "isRemote":
+ case "soundName":
+ case "setSoundName:":
+ case "hasActionButton":
+ case "setHasActionButton:":
+ case "activationType":
+ case "otherButtonTitle":
+ case "setOtherButtonTitle:":
+ return true;
+ }
+ break;
+ case "NSFileHandle": //Fails on Lion
+ case "NSUrlAuthenticationChallenge":
+ case "NSUrlCredential":
+ case "NSUrlProtectionSpace":
+ case "NSAppleEventDescriptor":
+ if (selectorName == "encodeWithCoder:" && !Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ case "NSValue":
+ switch (selectorName) {
+ case "SCNMatrix4Value":
+ case "SCNVector3Value":
+ case "SCNVector4Value":
+ case "valueWithSCNMatrix4:":
+ if (IntPtr.Size != 8)
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSession":
+ switch (selectorName) {
+ case "delegateQueue":
+ case "sessionDescription":
+ case "setSessionDescription:":
+ case "delegate":
+ if (Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSessionStreamTask":
+ switch (selectorName) {
+ case "captureStreams":
+ case "closeRead":
+ case "closeWrite":
+ case "readDataOfMinLength:maxLength:timeout:completionHandler:":
+ case "startSecureConnection":
+ case "stopSecureConnection":
+ case "writeData:timeout:completionHandler:":
+ if (Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSessionTask":
+ switch (selectorName) {
+ case "countOfBytesExpectedToReceive":
+ case "countOfBytesExpectedToSend":
+ case "countOfBytesReceived":
+ case "countOfBytesSent":
+ case "currentRequest":
+ case "error":
+ case "originalRequest":
+ case "response":
+ case "state":
+ case "taskDescription":
+ case "setTaskDescription:":
+ case "taskIdentifier":
+ if (Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSessionConfiguration":
+ if (Mac.IsAtLeast (10, 11))
+ return true;
+ break;
+ }
+ break;
+ case "MonoMac.AppKit":
+ case "AppKit":
+ switch (type.Name) {
+#if !XAMCORE_3_0 // These should be not be marked [Abstract] but can't fix w/o breaking change...
+ case "NSScrollView":
+ case "NSTextView":
+ switch (selectorName) {
+ case "contentViewAtIndex:effectiveCharacterRange:":
+ case "didReplaceCharacters":
+ case "drawCharactersInRange:forContentView:":
+ case "rectsForCharacterRange:":
+ case "replaceCharactersInRange:withString:":
+ case "scrollRangeToVisible:":
+ case "shouldReplaceCharactersInRanges:withStrings:":
+ case "stringAtIndex:effectiveRange:endsWithSearchBoundary:":
+ case "stringLength":
+ case "allowsMultipleSelection":
+ case "isEditable":
+ case "firstSelectedRange":
+ case "isSelectable":
+ case "selectedRanges":
+ case "setSelectedRanges:":
+ case "string":
+ case "visibleCharacterRanges":
+ return true;
+ }
+ break;
+#endif
+ case "NSMenuDelegate":
+ switch (selectorName) {
+#if !XAMCORE_3_0
+ case "menu:willHighlightItem:":
+ return true; // bound
+#endif
+ }
+ break;
+ case "NSResponder":
+ switch (selectorName) {
+ case "smartMagnifyWithEvent:":
+ case "quickLookWithEvent:":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ }
+ break;
+ case "NSViewController":
+ switch (selectorName) {
+ case "identifier": //
+ case "setIdentifier:":
+ // In Yosemite (but not before) NSViewController implements the NSUserInterfaceItemIdentification
+ // protocol (which brings a r/w Identifier property). We don't have any way of expressing that
+ // a type started implementing a protocol in a particular version, so just ignore these selectors.
+ if (!Mac.CheckSystemVersion (10, 10))
+ return true;
+ break;
+ }
+ break;
+ }
+ break;
+ // GameKit seems to follow a pattern were selectors are routed to an internal concrete type
+ case "MonoMac.GameKit":
+ case "GameKit":
+ switch (type.Name) {
+ case "GKTurnBasedExchange":
+ switch (selectorName) {
+ case "completionDate":
+ case "data":
+ case "exchangeID":
+ case "sendDate":
+ case "timeoutDate":
+ return true;
+ }
+ break;
+ case "GKTurnBasedExchangeReply":
+ switch (selectorName) {
+ case "data":
+ case "replyDate":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) GKDialogController_Concrete
+ case "GKDialogController":
+ switch (selectorName) {
+ case "parentWindow":
+ case "setParentWindow:":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) GKVoiceChat_Concrete
+ case "GKVoiceChat":
+ switch (selectorName) {
+ case "start":
+ case "stop":
+ case "setMute:forPlayer:":
+ case "name":
+ case "isActive":
+ case "setActive:":
+ case "volume":
+ case "setVolume:":
+ case "playerStateUpdateHandler":
+ case "setPlayerStateUpdateHandler:":
+ case "playerIDs":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) GKLeaderboard_Concrete
+ case "GKLeaderboard":
+ switch (selectorName) {
+ case "loadScoresWithCompletionHandler:":
+ case "timeScope":
+ case "setTimeScope:":
+ case "playerScope":
+ case "setPlayerScope:":
+ case "maxRange":
+ case "category":
+ case "setCategory:":
+ case "title":
+ case "range":
+ case "setRange:":
+ case "scores":
+ case "localPlayerScore":
+ case "groupIdentifier":
+ case "setGroupIdentifier:":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) GKLeaderboard_Concrete
+ case "GKLocalPlayer":
+ switch (selectorName) {
+ case "authenticateWithCompletionHandler:":
+ case "loadDefaultLeaderboardCategoryIDWithCompletionHandler:":
+ case "setDefaultLeaderboardCategoryID:completionHandler:":
+ case "authenticateHandler":
+ case "setAuthenticateHandler:":
+ case "loadFriendsWithCompletionHandler:":
+ case "isAuthenticated":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) GKMatch_Concrete
+ case "GKMatch":
+ switch (selectorName) {
+ case "sendData:toPlayers:withDataMode:error:":
+ case "sendDataToAllPlayers:withDataMode:error:":
+ case "disconnect":
+ case "voiceChatWithName:":
+ case "playerIDs":
+ case "delegate":
+ case "setDelegate:":
+ case "expectedPlayerCount":
+ return true;
+ }
+ break;
+ // looks like it's routed to (private) GKMatchmater_Concrete
+ case "GKMatchmaker":
+ switch (selectorName) {
+ case "inviteHandler":
+ case "setInviteHandler:":
+ case "findMatchForRequest:withCompletionHandler:":
+ case "findPlayersForHostedMatchRequest:withCompletionHandler:":
+ case "addPlayersToMatch:matchRequest:completionHandler:":
+ case "cancel":
+ case "queryPlayerGroupActivity:withCompletionHandler:":
+ case "queryActivityWithCompletionHandler:":
+ return true;
+ }
+ break;
+ }
+ break;
+ // Gone in Mavericks
+ case "MonoMac.StoreKit":
+ case "StoreKit":
+ switch (type.Name) {
+ case "SKPayment":
+ case "SKMutablePayment":
+ switch (selectorName) {
+ case "paymentWithProductIdentifier:":
+ if (Mac.CheckSystemVersion (10, 9))
+ return true;
+ break;
+ }
+ break;
+ }
+ break;
+ case "MonoMac.PdfKit": // Bug 20232
+ case "PdfKit":
+ switch (type.Name) {
+ case "PdfBorder": // Fails on Lion
+ case "PdfAnnotation":
+ if (selectorName == "encodeWithCoder:" && !Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ case "PdfView":
+ switch (selectorName) {
+#if !XAMCORE_3_0
+ case "menu:willHighlightItem:":
+ return true;
+#endif
+ }
+ break;
+ }
+ break;
+ case "MonoMac.SceneKit":
+ case "SceneKit":
+ switch (type.Name) {
+ case "SCNGeometryElement":
+ // Ignore on 10.8 where SCNGeometryPrimitiveType is int (32), but
+ // on 10.9+ is NSInteger/nint (32/64). SceneKit is next to useless
+ // on 10.8 anyway. -abock
+ if (selectorName == "primitiveType" && Mac.CheckSystemVersion (10, 8))
+ return true;
+ // fall through
+ goto case "SCNCamera";
+ case "SCNCamera":
+ case "SCNGeometry":
+ case "SCNGeometrySource":
+ case "SCNLight":
+ case "SCNMaterial":
+ case "SCNMaterialProperty":
+ case "SCNNode":
+ case "SCNProgram":
+ case "SCNScene":
+ case "SCNMorpher":
+ case "SCNSkinner":
+ case "SCNConstraint":
+ case "SCNLevelOfDetail":
+ // The NSSecureCoding protocol was added to these types in Yosemite,
+ // and we can't (yet?) describe "type added protocol P in version X.Y"
+ // with our AvailabilityAttribute, so do this check manually.
+ if (selectorName == "encodeWithCoder:" && !Mac.CheckSystemVersion (10, 10))
+ return true;
+ break;
+ }
+
+ switch (type.Name) {
+ case "SCNGeometry":
+ // SCNGeometry added the SCNShadable protocol in 10.9, which brings in the 'program' selector.
+ switch (selectorName) {
+ case "program":
+ case "setProgram:":
+ if (!Mac.CheckSystemVersion (10, 9))
+ return true;
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ return base.Skip (type, selectorName);
+ }
+
+ static List do_not_dispose = new List ();
+
+ protected override void Dispose (NSObject obj, Type type)
+ {
+ switch (type.FullName) {
+ // FIXME: those crash the application when Dispose is called
+ case "MonoMac.AVFoundation.AVAudioRecorder":
+ case "AVFoundation.AVAudioRecorder":
+ case "MonoMac.Foundation.NSUrlConnection":
+ case "Foundation.NSUrlConnection":
+
+ // 10.8:
+ case "MonoMac.Accounts.ACAccount": // maybe the default .ctor is not allowed ?
+ case "Accounts.ACAccount":
+ case "MonoMac.Accounts.ACAccountCredential":
+ case "Accounts.ACAccountCredential":
+ case "MonoMac.Accounts.ACAccountStore":
+ case "Accounts.ACAccountStore":
+ case "MonoMac.Accounts.ACAccountType":
+ case "Accounts.ACAccountType":
+ do_not_dispose.Add (obj);
+ break;
+ default:
+ base.Dispose (obj, type);
+ break;
+ }
+ }
+
+ protected override bool CheckResponse (bool value, Type actualType, MethodBase method, ref string name)
+ {
+ var declaredType = method.DeclaringType;
+
+ switch (name) {
+ // NSDraggingDestination protocol
+ case "concludeDragOperation:": // e.g. NSTokenField
+ case "draggingEnded:": // e.g. NSMatrix
+ case "draggingExited:": // e.g. NSTokenField
+ case "draggingUpdated:": // e.g. NSTokenField
+ case "performDragOperation:": // e.g. NSTokenField
+ case "prepareForDragOperation:": // e.g. NSTokenField
+ case "wantsPeriodicDraggingUpdates": // e.g. NSBrowser - optional, [DefaultValue(true)] if it does not exists
+ return true;
+ // NSDraggingSource
+ case "draggedImage:beganAt:": // e.g. NSTextView
+ case "draggedImage:endedAt:deposited:": // e.g. NSTableView
+ case "draggedImage:movedTo:": // e.g. NSCollectionView
+ case "ignoreModifierKeysWhileDragging": // e.g. NSTextView
+ case "namesOfPromisedFilesDroppedAtDestination:": // e.g. NSTextView
+ return true;
+ // NSAnimatablePropertyContainer
+ case "animationForKey:": // e.g. NSViewAnimation
+ case "animator":
+ case "animations":
+ case "setAnimations:":
+ return true;
+ // NSTypeSetter - Layout Phase Interface (needs to be overridden, not really part of the provided types)
+ case "willSetLineFragmentRect:forGlyphRange:usedRect:baselineOffset:":
+ case "shouldBreakLineByWordBeforeCharacterAtIndex:":
+ case "shouldBreakLineByHyphenatingBeforeCharacterAtIndex:":
+ case "hyphenationFactorForGlyphAtIndex:":
+ case "hyphenCharacterForGlyphAtIndex:":
+ case "boundingBoxForControlGlyphAtIndex:forTextContainer:proposedLineFragment:glyphPosition:characterIndex:":
+ return true;
+ // in NSView documentation but defined in NSClipView - no answers to call
+ case "scrollClipView:toPoint:":
+ return true;
+ // IKFilterBrowserPanel ??? not clear why
+ case "finish:":
+ return true;
+ // IKFilterUIView
+ case "viewForUIConfiguration:excludedKeys:": // [Target] on CIFilter
+ return true;
+ // NSDictionaryEnumerator
+ case "fileModificationDate":
+ case "fileType":
+ case "filePosixPermissions":
+ case "fileOwnerAccountName":
+ case "fileGroupOwnerAccountName":
+ case "fileSystemNumber":
+ case "fileSystemFileNumber":
+ case "fileExtensionHidden":
+ case "fileHFSCreatorCode":
+ case "fileHFSTypeCode":
+ case "fileIsImmutable":
+ case "fileIsAppendOnly":
+ case "fileCreationDate":
+ case "fileOwnerAccountID":
+ case "fileGroupOwnerAccountID":
+ return true; // all [Target] on NSDictionary
+ // SBObject
+ case "get":
+ return true;
+
+ // NSCoder - documented as available in 10.8
+ case "allowedClasses":
+ case "requiresSecureCoding":
+ return true;
+
+ // NSFileManager
+ case "ubiquityIdentityToken": // documented in 10.8
+ return true;
+ // NS[Mutable]UrlRequest
+ case "allowsCellularAccess": // documented in 10.8
+ case "setAllowsCellularAccess:": // documented in 10.8
+ return true;
+ // NSString
+ case "capitalizedStringWithLocale:": // documented in 10.8
+ case "lowercaseStringWithLocale:": // documented in 10.8
+ case "uppercaseStringWithLocale:": // documented in 10.8
+ return true;
+ // AVVideoComposition
+ case "isValidForAsset:timeRange:validationDelegate:": // documented in 10.8
+ return true;
+ // AVPlayer
+ case "setRate:time:atHostTime:": // 10.8+
+ case "prerollAtRate:completionHandler:": // 10.8+
+ case "cancelPendingPrerolls": // 10.8+
+ case "masterClock": // 10.8+
+ case "setMasterClock:": // 10.8+
+ // NSDateComponents
+ case "isLeapMonth": // 10.8+
+ case "setLeapMonth:": // 10.8+
+ // NSFileCoordinator
+ case "itemAtURL:willMoveToURL:": // 10.8+
+ return true; // documented (but does not respond)
+
+ // MonoMac.CoreImage.CIDetector (10.8+)
+ case "featuresInImage:options:":
+ // MonoMac.CoreImage.CIFaceFeature (10.8+)
+ case "hasTrackingID":
+ case "trackingID":
+ case "hasTrackingFrameCount":
+ case "trackingFrameCount":
+ // MonoMac.CoreImage.CIImage : only in 10.8+
+ case "properties": // only documented in header files
+ case "autoAdjustmentFilters":
+ case "autoAdjustmentFiltersWithOptions:":
+ // MonoMac.AVFoundation.AVAssetExportSession (10.8+)
+ case "asset":
+ // MonoMac.AVFoundation.AVAssetReaderOutput
+ case "alwaysCopiesSampleData":
+ case "setAlwaysCopiesSampleData:":
+ // MonoMac.AVFoundation.AVAssetTrack
+ case "isPlayable":
+ // MonoMac.AVFoundation.AVAudioPlayer (10.8+)
+ case "enableRate":
+ case "setEnableRate:":
+ case "rate":
+ case "setRate:":
+ // MonoMac.AVFoundation.AVMutableCompositionTrack
+ case "insertTimeRanges:ofTracks:atTime:error:":
+ // MonoMac.AVFoundation.AVPlayerItem
+ case "addOutput:":
+ case "removeOutput:":
+ case "canPlayFastReverse":
+ case "canPlayFastForward":
+ case "canPlaySlowForward":
+ case "canPlayReverse":
+ case "canPlaySlowReverse":
+ case "canStepForward":
+ case "canStepBackward":
+ case "outputs":
+ case "timebase":
+ // MonoMac.CoreAnimation.CAAnimation : only on OSX, added for SceneKit
+ case "usesSceneTimeBase":
+ case "setUsesSceneTimeBase:":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ case "initWithString:":
+ if (declaredType.Name == "NSTextStorage")
+ return true;
+ break;
+ }
+
+ switch (declaredType.Name) {
+ case "NSUrlSession":
+ case "Foundation.NSUrlSession":
+ switch (name) {
+ case "delegateQueue":
+ case "sessionDescription":
+ case "setSessionDescription:":
+ case "delegate":
+ if (!Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ }
+ break;
+ case "NSUrlSessionTask":
+ case "Foundation.NSUrlSessionTask":
+ switch (name) {
+ case "countOfBytesExpectedToReceive":
+ case "countOfBytesExpectedToSend":
+ case "countOfBytesReceived":
+ case "countOfBytesSent":
+ case "currentRequest":
+ case "error":
+ case "originalRequest":
+ case "response":
+ case "state":
+ case "taskDescription":
+ case "setTaskDescription:":
+ case "taskIdentifier":
+ case "priority":
+ case "setPriority:":
+ if (!Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ }
+ break;
+ case "Foundation.NSUrlSessionStreamTask":
+ case "NSUrlSessionStreamTask":
+ switch (name) {
+ case "captureStreams":
+ case "closeRead":
+ case "closeWrite":
+ case "readDataOfMinLength:maxLength:timeout:completionHandler:":
+ case "startSecureConnection":
+ case "stopSecureConnection":
+ case "writeData:timeout:completionHandler:":
+ if (!Mac.CheckSystemVersion (10, 11))
+ return true;
+ break;
+ }
+ break;
+ }
+
+// Console.WriteLine ("{0} {1}", declaredType, name);
+ return base.CheckResponse (value, actualType, method, ref name);
+ }
+
+ protected override bool CheckStaticResponse (bool value, Type actualType, Type declaredType, ref string name)
+ {
+ switch (name) {
+ // 10.7 exceptions
+
+ // NSAnimatablePropertyContainer protocol (10.7) -> NSViewAnimation
+ case "defaultAnimationForKey:":
+ return true;
+
+ // 10.8 exceptions
+
+ // GKPlayer - documented as available in 10.8
+ case "loadPlayersForIdentifiers:withCompletionHandler:":
+ // SLRequest - documented as available in 10.8
+ case "requestForServiceType:requestMethod:URL:parameters:":
+ // NSDictionary - documented as available in 10.8
+ case "dictionaryWithSharedKeySet:":
+ case "sharedKeySetForKeys:":
+ // AVMetadataItem - documented as available in 10.8
+ case "metadataItemsFromArray:filteredAndSortedAccordingToPreferredLanguages:":
+ return true;
+ }
+ return base.CheckStaticResponse (value, actualType, declaredType, ref name);
+ }
+
+ protected override bool SkipInit (string selector, MethodBase m)
+ {
+ switch (selector) {
+#if !XAMCORE_3_0
+ // DomEvent
+ case "initEvent:canBubbleArg:cancelableArg:":
+ // DomOverflowEvent
+ case "initOverflowEvent:horizontalOverflow:verticalOverflow:":
+ // DomUIEvent
+ case "initUIEvent:canBubble:cancelable:view:detail:":
+ // DomKeyboardEvent
+ case "initKeyboardEvent:canBubble:cancelable:view:keyIdentifier:keyLocation:ctrlKey:altKey:shiftKey:metaKey:altGraphKey:":
+ case "initKeyboardEvent:canBubble:cancelable:view:keyIdentifier:keyLocation:ctrlKey:altKey:shiftKey:metaKey:":
+ // DomMouseEvent
+ case "initMouseEvent:canBubble:cancelable:view:detail:screenX:screenY:clientX:clientY:ctrlKey:altKey:shiftKey:metaKey:button:relatedTarget:":
+ // DomWheelEvent
+ case "initWheelEvent:wheelDeltaY:view:screenX:screenY:clientX:clientY:ctrlKey:altKey:shiftKey:metaKey:":
+ // QTMovie
+ case "movieWithTimeRange:error:":
+ case "initWithQuickTimeMedia:error:":
+ // NSAppleEventDescriptor
+ case "initListDescriptor":
+ case "initRecordDescriptor":
+ // NSAnimation
+ case "initWithDuration:animationCurve:":
+ return true;
+#endif
+ // NSImage
+ case "initWithDataIgnoringOrientation:":
+ var mi = m as MethodInfo;
+ return mi != null && !mi.IsPublic && mi.ReturnType.Name == "IntPtr";
+ default:
+ return base.SkipInit (selector, m);
+ }
+ }
+ }
+}
diff --git a/tests/dontlink-mac/MacApiSignatureTest.cs b/tests/dontlink-mac/MacApiSignatureTest.cs
new file mode 100644
index 000000000000..ec400e542580
--- /dev/null
+++ b/tests/dontlink-mac/MacApiSignatureTest.cs
@@ -0,0 +1,235 @@
+//
+// Test the generated API selectors against typos or non-existing cases
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class MacSignatureTest : ApiSignatureTest {
+
+ static MacSignatureTest ()
+ {
+ Runtime.RegisterAssembly (typeof (NSObject).Assembly);
+ }
+
+ public MacSignatureTest ()
+ {
+ ContinueOnFailure = true;
+ //LogProgress = true;
+ }
+
+ protected override bool Skip (Type type, MethodBase method, string selector)
+ {
+ switch (type.Namespace) {
+ case "MonoMac.GameKit":
+ case "GameKit":
+ case "MonoMac.StoreKit":
+ case "StoreKit":
+ if (!Mac.CheckSystemVersion (10, 8))
+ return true;
+ break;
+ case "MonoMac.SceneKit":
+ case "SceneKit":
+ // SceneKit is half-baked at best, and they broke compatibility significantly
+ // from Mountain Lion to Mavericks, so just ignore all problems there.
+ if (!Mac.CheckSystemVersion (10, 9))
+ return true;
+ break;
+ }
+
+ // Bug 20232 - This is a hack.
+ if (selector == "geometryElementWithData:primitiveType:primitiveCount:bytesPerIndex:")
+ return true;
+
+ switch (type.Name) {
+ case "AVPlayerItemOutput":
+ case "AVPlayerItemVideoOutput":
+ case "NSSharingService":
+ case "NSSharingServicePicker":
+ case "NSUserNotification":
+ case "NSUserNotificationCenter":
+ case "NSUuid":
+ return !Mac.CheckSystemVersion (10, 8);
+
+ case "CALayer":
+ case "CAEmitterLayer":
+ case "CAGradientLayer":
+ case "CAOpenGLLayer":
+ case "CAReplicatorLayer":
+ case "CAScrollLayer":
+ case "CAShapeLayer":
+ case "CATextLayer":
+ case "CATiledLayer":
+ case "CATransformLayer":
+ case "QTCaptureLayer":
+ case "QTMovieLayer":
+ case "QCCompositionLayer":
+ case "AVCaptureVideoPreviewLayer":
+ case "AVPlayerLayer":
+ case "SCNLayer":
+ switch (selector) {
+ // CAGradientLayer 'instance MonoMac.CoreAnimation.CAConstraint[] get_Constraints()' selector: constraints == @?@:
+ case "constraints":
+ // CAGradientLayer 'instance Void set_Constraints(MonoMac.CoreAnimation.CAConstraint[])' selector: setConstraints: == v@:@?
+ case "setConstraints:":
+ return true;
+ }
+ break;
+ case "SCNSkinner":
+ return !Mac.CheckSystemVersion (10, 9);
+ case "NSGradient":
+ switch (selector) {
+ case "initWithColorsAndLocations:": // variable length parameters ...
+ case "initWithColors:atLocations:colorSpace:": // void * -> nfloat [] (internal)
+ return true;
+ }
+ break;
+ case "AVAudioIONode":
+ case "AVAudioUnit":
+ switch (selector) {
+ case "audioUnit": // ^{ComponentInstanceRecord=[1l], tested to work in an apitest
+ return true;
+ }
+ break;
+ }
+ return base.Skip (type, method, selector);
+ }
+
+ protected override int Size (Type t, bool simd = false)
+ {
+ switch (t.FullName) {
+ case "GameKit.GKGameCenterViewControllerState":
+ case "AppKit.NSOpenGLContextParameter":
+ // NSOpenGLContextParameter and GKGameCenterViewControllerState are anonymous enums in 10.9, but an NSInteger in 10.10.
+ if (IntPtr.Size == 8 && !Mac.CheckSystemVersion (10, 10))
+ return 4;
+ break;
+ }
+
+ return base.Size (t, simd);
+ }
+
+ protected override bool IsValidStruct (Type type, string structName)
+ {
+ switch (structName) {
+ case "_NSPoint":
+#if XAMCORE_2_0
+ return type.FullName == "CoreGraphics.CGPoint";
+#else
+ return type.FullName == "System.Drawing.PointF";
+#endif
+ case "_NSRect":
+#if XAMCORE_2_0
+ return type.FullName == "CoreGraphics.CGRect";
+#else
+ return type.FullName == "System.Drawing.RectangleF";
+#endif
+ case "_NSSize":
+#if XAMCORE_2_0
+ return type.FullName == "CoreGraphics.CGSize";
+#else
+ return type.FullName == "System.Drawing.SizeF";
+#endif
+ case "_SCNVector3":
+ return type.Name == "SCNVector3";
+ case "_SCNVector4":
+ return type.Name == "SCNVector4";
+ // CIImage 'static MonoMac.CoreImage.CIImage FromImageBuffer(MonoMac.CoreVideo.CVImageBuffer)' selector: imageWithCVImageBuffer: == @12@0:4^{__CVBuffer=}8
+ // AVAssetWriterInputPixelBufferAdaptor 'instance Boolean AppendPixelBufferWithPresentationTime(MonoMac.CoreVideo.CVPixelBuffer, CMTime)' selector: appendPixelBuffer:withPresentationTime: == c36@0:4^{__CVBuffer=}8{?=qiIq}12
+ case "__CVBuffer":
+ return type.Name == "CVImageBuffer" || type.Name == "CVPixelBuffer";;
+ case "CATransform3D":
+ return type.Name == "CATransform3D" || type.Name == "SCNMatrix4";
+ case "SCNVector4":
+ return type.Name == "SCNVector4" || type.Name == "SCNQuaternion"; // "SCNQuaternion is a SCNVector 3, then a nfloat, so same structure
+ }
+ return base.IsValidStruct (type, structName);
+ }
+
+ // only handle exception here (to return true) otherwise call base to deal with it
+ protected override bool Check (string encodedType, Type type)
+ {
+ switch (encodedType) {
+ case "^{OpaqueSecTrustRef=}":
+ // On 10.7 and 10.8:
+ // [FAIL] Signature failure in MonoMac.Foundation.NSUrlCredential initWithTrust: Parameter 'trust' (#1) is encoded as '^{OpaqueSecTrustRef=}' and bound as 'MonoMac.Security.SecTrust'
+ return type.Name == "SecTrust" || type.FullName == "System.IntPtr";
+ }
+ return base.Check (encodedType, type);
+ }
+
+ // only handle exception here (to return true) otherwise call base to deal with it
+ // `caller` is provided to make it easier to detect "special" cases
+ protected override bool Check (char encodedType, Type type)
+ {
+ switch (encodedType) {
+ case 'i':
+ switch (type.FullName) {
+ case "System.nuint":
+ case "System.UInt32":
+ // sign-ness mis-binding, not critical
+ // Signature failure in MonoMac.AppKit.NSViewController presentViewController:asPopoverRelativeToRect:ofView:preferredEdge:behavior: Parameter 'preferredEdge' (#4) is encoded as 'i' and bound as 'System.UInt32'
+ return true;
+ case "GameKit.GKGameCenterViewControllerState":
+ case "AppKit.NSOpenGLContextParameter":
+ // NSOpenGLContextParameter and GKGameCenterViewControllerState are anonymous enums in 10.9, but an NSInteger in 10.10.
+ if (IntPtr.Size == 8 && !Mac.CheckSystemVersion (10, 10))
+ return true;
+ break;
+ }
+ break;
+ // unsigned 32 bits
+ case 'I':
+ switch (type.FullName) {
+ case "System.Int32":
+ // sign-ness mis-binding, several of them (not critical)
+ // NSActionCell 'instance Int32 get_MnemonicLocation()' selector: mnemonicLocation == I8@0:4
+ // NSPathCell 'instance Int32 get_MnemonicLocation()' selector: mnemonicLocation == I8@0:4
+ // SCNText 'instance Void InsertMaterial(MonoMac.SceneKit.SCNMaterial, Int32)' selector: insertMaterial:atIndex: == v16@0:4@8I12
+ return true;
+ }
+ break;
+ // unsigned 32 bits
+ case 'L':
+ switch (type.FullName) {
+ // sign-ness mis-binding (not critical) e.g.
+ // CAMediaTimingFunction 'instance Void GetControlPointAtIndex(Int32, IntPtr)' selector: getControlPointAtIndex:values: == v16@0:4L8[2f]12
+ case "System.Int32":
+ return true;
+ }
+ break;
+ // unsigned 64 bits
+ case 'Q':
+ switch (type.FullName) {
+ // sign-ness mis-binding (not critical) e.g.
+ // NSEvent 'instance Int64 get_UniqueID()' selector: uniqueID == Q8@0:4
+ case "System.Int64":
+ return true;
+ }
+ break;
+ }
+ return base.Check (encodedType, type);
+ }
+ }
+}
diff --git a/tests/dontlink-mac/MacApiWeakPropertyTest.cs b/tests/dontlink-mac/MacApiWeakPropertyTest.cs
new file mode 100644
index 000000000000..fc1bc5510b4c
--- /dev/null
+++ b/tests/dontlink-mac/MacApiWeakPropertyTest.cs
@@ -0,0 +1,30 @@
+using System;
+
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoMac.Foundation;
+#endif
+
+using NUnit.Framework;
+
+using TouchUnit.Bindings;
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class MacApiWeakPropertyTest : ApiWeakPropertyTest {
+ protected override bool Skip (Type type)
+ {
+ switch (type.Name) {
+ case "CATextLayer": // CATextLayer.WeakFont is done correctly by hand
+ return true;
+ case "NSAttributedStringDocumentAttributes": // NSAttributedStringDocumentAttributes.WeakDocumentType is done by hand, not a binding
+ return true;
+ }
+ return base.Skip (type);
+ }
+ }
+}
diff --git a/tests/dontlink-mac/MacCoreImageFiltersTest.cs b/tests/dontlink-mac/MacCoreImageFiltersTest.cs
new file mode 100644
index 000000000000..6a74472c936f
--- /dev/null
+++ b/tests/dontlink-mac/MacCoreImageFiltersTest.cs
@@ -0,0 +1,62 @@
+//
+// Test the generated API for all Mac CoreImage filters
+//
+// Authors:
+// Sebastien Pouliot
+// Alex Soto
+//
+// Copyright 2013, 2015 Xamarin Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+using NUnit.Framework;
+using TouchUnit.Bindings;
+
+#if XAMCORE_2_0
+using CoreImage;
+using Foundation;
+using ObjCRuntime;
+#elif MONOMAC
+using MonoMac.CoreImage;
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#endif
+
+namespace MonoMacFixtures {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class MacCoreImageFiltersTest : ApiCoreImageFiltersTest
+ {
+ protected override bool Skip (string nativeName)
+ {
+ switch (nativeName) {
+ case "CIMaskedVariableBlur": // Appears removed in 10.11 but not documented
+ if (Mac.CheckSystemVersion (10, 11))
+ return true;
+ return false;
+ case "CICMYKHalftone": // Renamed as CICmykHalftone
+ return true;
+ default:
+ return base.Skip (nativeName);
+ }
+ }
+ }
+}
+
diff --git a/tests/dontlink-mac/dontlink-mac.csproj b/tests/dontlink-mac/dontlink-mac.csproj
new file mode 100644
index 000000000000..586104563d72
--- /dev/null
+++ b/tests/dontlink-mac/dontlink-mac.csproj
@@ -0,0 +1,118 @@
+
+
+
+ Debug
+ x86
+ {FD385098-B3FD-4331-92BF-CC1F918E3334}
+ {42C0BBD9-55CE-4FC1-8D90-A7348ABAFB23};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ dontlink
+ dontlink-mac
+ Resources
+ v4.5
+
+
+ true
+ full
+ false
+ bin\x86\Debug
+ DEBUG;MONOMAC
+ prompt
+ 4
+ false
+ false
+ Mac Developer
+ false
+ false
+ false
+ false
+ x86
+
+
+ true
+ bin\x86\Release
+ MONOMAC
+ prompt
+ 4
+ false
+ true
+ Developer ID Application
+ true
+ false
+ true
+ false
+ SdkOnly
+ x86
+
+
+
+
+
+
+
+
+
+ ..\..\..\xamarin-macios\external\guiunit\bin\net_4_5\GuiUnit.exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CoreSelectorTest.cs
+
+
+ ApiBaseTest.cs
+
+
+ ApiCtorInitTest.cs
+
+
+ ApiFieldTest.cs
+
+
+ ApiSelectorTest.cs
+
+
+ EnvironmentVariable.cs
+
+
+ ApiCoreImageFiltersTest.cs
+
+
+ ApiPInvokeTest.cs
+
+
+ ApiProtocolTest.cs
+
+
+ ApiSignatureTest.cs
+
+
+ ApiStructTest.cs
+
+
+ PlatformInfo.cs
+
+
+
+ ApiWeakPropertyTest.cs
+
+
+
+
+ MacTestMain.cs
+
+
+
+
+
+
+
diff --git a/tests/framework-test/AppDelegate.cs b/tests/framework-test/AppDelegate.cs
new file mode 100644
index 000000000000..652920d9e297
--- /dev/null
+++ b/tests/framework-test/AppDelegate.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+using MonoTouch.NUnit.UI;
+
+namespace frameworktest
+{
+ // The UIApplicationDelegate for the application. This class is responsible for launching the
+ // User Interface of the application, as well as listening (and optionally responding) to
+ // application events from iOS.
+ [Register ("AppDelegate")]
+ public partial class AppDelegate : UIApplicationDelegate
+ {
+ // class-level declarations
+ UIWindow window;
+ TouchRunner runner;
+
+ //
+ // This method is invoked when the application has loaded and is ready to run. In this
+ // method you should instantiate the window, load the UI into it and then make the window
+ // visible.
+ //
+ // You have 17 seconds to return from this method, or iOS will terminate your application.
+ //
+ public override bool FinishedLaunching (UIApplication app, NSDictionary options)
+ {
+ // create a new window instance based on the screen size
+ window = new UIWindow (UIScreen.MainScreen.Bounds);
+ runner = new TouchRunner (window);
+
+ // register every tests included in the main application/assembly
+ runner.Add (System.Reflection.Assembly.GetExecutingAssembly ());
+
+ window.RootViewController = new UINavigationController (runner.GetViewController ());
+
+ // make the window visible
+ window.MakeKeyAndVisible ();
+
+ return true;
+ }
+ }
+}
+
diff --git a/tests/framework-test/Entitlements.plist b/tests/framework-test/Entitlements.plist
new file mode 100644
index 000000000000..9ae599370b42
--- /dev/null
+++ b/tests/framework-test/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/tests/framework-test/FrameworkTests.cs b/tests/framework-test/FrameworkTests.cs
new file mode 100644
index 000000000000..c30bb9f073a8
--- /dev/null
+++ b/tests/framework-test/FrameworkTests.cs
@@ -0,0 +1,47 @@
+//
+// Framework tests
+//
+// Authors:
+// Rolf Bjarne Kvinge
+//
+// Copyright 2015 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+#if XAMCORE_2_0
+
+using MonoTouch;
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+
+using NUnit.Framework;
+
+using Bindings.Test;
+
+namespace MonoTouchFixtures {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class FrameworkTests {
+ [Test]
+ public void CFunction ()
+ {
+ Assert.AreEqual (42, CFunctions.theUltimateAnswer (), "a");
+ Assert.AreEqual (42, CFunctions.object_theUltimateAnswer (), "object");
+ Assert.AreEqual (42, CFunctions.ar_theUltimateAnswer (), "ar");
+ }
+
+ [Test]
+ public void ObjCClass ()
+ {
+ using (var obj = new FrameworkTest ()) {
+ Assert.AreEqual (42, obj.Func (), "a");
+ }
+ }
+ }
+}
+
+#endif
diff --git a/tests/framework-test/Info.plist b/tests/framework-test/Info.plist
new file mode 100644
index 000000000000..63055db162d1
--- /dev/null
+++ b/tests/framework-test/Info.plist
@@ -0,0 +1,40 @@
+
+
+
+
+ CFBundleName
+ framework-test
+ CFBundleIdentifier
+ com.xamarin.framework-test
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ MinimumOSVersion
+ 8.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/tests/framework-test/Main.cs b/tests/framework-test/Main.cs
new file mode 100644
index 000000000000..b45a64c2cbf2
--- /dev/null
+++ b/tests/framework-test/Main.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+
+namespace frameworktest
+{
+ public class Application
+ {
+ // This is the main entry point of the application.
+ static void Main (string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main (args, null, "AppDelegate");
+ }
+ }
+}
diff --git a/tests/framework-test/Resources/Default-568h@2x.png b/tests/framework-test/Resources/Default-568h@2x.png
new file mode 100644
index 000000000000..29973dcbed50
Binary files /dev/null and b/tests/framework-test/Resources/Default-568h@2x.png differ
diff --git a/tests/framework-test/framework-test.csproj b/tests/framework-test/framework-test.csproj
new file mode 100644
index 000000000000..bd23088c4f35
--- /dev/null
+++ b/tests/framework-test/framework-test.csproj
@@ -0,0 +1,107 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 8.0.30703
+ 2.0
+ {2ECCE3D0-AAD1-46B9-B190-B567249DCF9C}
+ Exe
+ frameworktest
+ Resources
+ frameworktest
+ MonoTouch
+
+
+ true
+ full
+ false
+ bin\iPhoneSimulator\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ i386
+ None
+ true
+ true
+ true
+ true
+ iPhone Developer
+ true
+
+
+ full
+ true
+ bin\iPhone\Release
+ prompt
+ 4
+ false
+ ARMv7
+ Entitlements.plist
+ true
+ true
+ iPhone Developer
+ true
+
+
+ full
+ true
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ false
+ i386
+ None
+ true
+ iPhone Developer
+ true
+
+
+ true
+ full
+ false
+ bin\iPhone\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ ARMv7
+ Entitlements.plist
+ true
+ iPhone Developer
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {E40B0B77-3467-4891-9117-7AF8F248E306}
+ bindings-framework-test
+
+
+
\ No newline at end of file
diff --git a/tests/fsharp/AppDelegate.fs b/tests/fsharp/AppDelegate.fs
new file mode 100644
index 000000000000..6332cac3e3bf
--- /dev/null
+++ b/tests/fsharp/AppDelegate.fs
@@ -0,0 +1,35 @@
+namespace fsharp
+
+#if !__WATCHOS__
+open System
+open System.Reflection
+
+#if __UNIFIED__
+open UIKit
+open Foundation
+#else
+open MonoTouch.UIKit
+open MonoTouch.Foundation
+#endif
+
+open MonoTouch.NUnit.UI
+
+[]
+type AppDelegate () =
+ inherit UIApplicationDelegate ()
+
+ let mutable window = Unchecked.defaultof
+ let mutable runner = Unchecked.defaultof
+
+ // This method is invoked when the application is ready to run.
+ override this.FinishedLaunching (app, options) =
+ window <- new UIWindow (UIScreen.MainScreen.Bounds)
+ runner <- new TouchRunner (window)
+
+ runner.Add (Assembly.GetExecutingAssembly ())
+
+ window.RootViewController <- new UINavigationController (runner.GetViewController ())
+ window.MakeKeyAndVisible ()
+
+ true
+#endif // !__WATCHOS__
diff --git a/tests/fsharp/Entitlements.plist b/tests/fsharp/Entitlements.plist
new file mode 100644
index 000000000000..9ae599370b42
--- /dev/null
+++ b/tests/fsharp/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/tests/fsharp/FSharpTests.fs b/tests/fsharp/FSharpTests.fs
new file mode 100644
index 000000000000..5b52270e5a7d
--- /dev/null
+++ b/tests/fsharp/FSharpTests.fs
@@ -0,0 +1,21 @@
+namespace fsharp
+
+open System
+open System.Reflection
+
+#if __UNIFIED__
+open UIKit
+open Foundation
+#else
+open MonoTouch.UIKit
+open MonoTouch.Foundation
+#endif
+
+open NUnit.Framework
+
+[]
+[]
+type FSharpTest () =
+ []
+ member x.Func () =
+ ()
diff --git a/tests/fsharp/Info.plist b/tests/fsharp/Info.plist
new file mode 100644
index 000000000000..99e019b9a1d0
--- /dev/null
+++ b/tests/fsharp/Info.plist
@@ -0,0 +1,41 @@
+
+
+
+
+ CFBundleName
+ fsharptest
+ CFBundleIdentifier
+ com.xamarin.fsharptest
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortraitUpsideDown
+
+ MinimumOSVersion
+ 5.1.1
+
+
diff --git a/tests/fsharp/Main.fs b/tests/fsharp/Main.fs
new file mode 100644
index 000000000000..c726fe69a8af
--- /dev/null
+++ b/tests/fsharp/Main.fs
@@ -0,0 +1,17 @@
+namespace Test
+
+#if __UNIFIED__
+open UIKit
+#else
+open MonoTouch.UIKit
+#endif
+
+#if !__WATCHOS__
+
+module Main =
+ []
+ let main args =
+ UIApplication.Main(args, null, "AppDelegate")
+ 0
+
+#endif
diff --git a/tests/fsharp/fsharp.fsproj b/tests/fsharp/fsharp.fsproj
new file mode 100644
index 000000000000..37e7353b7757
--- /dev/null
+++ b/tests/fsharp/fsharp.fsproj
@@ -0,0 +1,104 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 8.0.30703
+ 2.0
+ {7862FE5A-530A-4651-825F-C80836B0A3A1}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{F2A71F9B-5D33-465A-A702-920D77279786}
+ Exe
+ fsharp
+ fsharp
+ Resources
+ MonoTouch
+
+
+ true
+ full
+ false
+ bin\iPhoneSimulator\Debug
+ DEBUG
+ prompt
+ false
+ iPhone Developer
+ true
+ false
+ true
+ HttpClientHandler
+ true
+ true
+ None
+ i386
+
+
+ true
+ bin\iPhone\Release
+
+ prompt
+ false
+ iPhone Developer
+ HttpClientHandler
+ true
+ true
+ true
+ Entitlements.plist
+ ARMv7
+ true
+ None
+
+
+ true
+ bin\iPhoneSimulator\Release
+
+ prompt
+ false
+ iPhone Developer
+ HttpClientHandler
+ true
+ true
+ None
+ i386
+ true
+
+
+ true
+ full
+ false
+ bin\iPhone\Debug
+ DEBUG
+ prompt
+ false
+ iPhone Developer
+ true
+ true
+ false
+ true
+ HttpClientHandler
+ true
+ true
+ true
+ Entitlements.plist
+ None
+ ARMv7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/fsharplibrary/AssemblyInfo.fs b/tests/fsharplibrary/AssemblyInfo.fs
new file mode 100644
index 000000000000..8d3e9f33b0af
--- /dev/null
+++ b/tests/fsharplibrary/AssemblyInfo.fs
@@ -0,0 +1,20 @@
+namespace fsharplibrary
+open System.Reflection
+open System.Runtime.CompilerServices
+
+[]
+[]
+[]
+[]
+[]
+[]
+[]
+
+// The assembly version has the format {Major}.{Minor}.{Build}.{Revision}
+
+[]
+
+//[]
+//[]
+
+()
diff --git a/tests/fsharplibrary/ObjCRuntime/RegistrarTest.fs b/tests/fsharplibrary/ObjCRuntime/RegistrarTest.fs
new file mode 100644
index 000000000000..28831acb158f
--- /dev/null
+++ b/tests/fsharplibrary/ObjCRuntime/RegistrarTest.fs
@@ -0,0 +1,33 @@
+namespace MonoTouchFixtures
+
+open System
+#if __UNIFIED__
+open Foundation
+#else
+open MonoTouch.Foundation
+#endif
+
+type Registrar_OutExportClass() =
+ inherit NSObject()
+
+ abstract member Func: NSObject byref -> IntPtr
+
+ []
+ default this.Func ([] value: NSObject byref) =
+ let tmp = if Object.ReferenceEquals (value, null) then IntPtr.Zero else value.Handle
+ let value = new NSObject ()
+ tmp
+
+type Registrar_OutExportDerivedClass() =
+ inherit Registrar_OutExportClass()
+
+ override this.Func (value: NSObject byref) =
+ let tmp = if Object.ReferenceEquals (value, null) then IntPtr.Zero else value.Handle
+ let value = new NSDate ()
+ tmp
+
+type ClassWithAnonymousFSharpClass() =
+ let anonymous = {
+ new NSObject () with
+ member x.ToString() = "ToString"
+ }
diff --git a/tests/fsharplibrary/fsharplibrary.fsproj b/tests/fsharplibrary/fsharplibrary.fsproj
new file mode 100644
index 000000000000..833a1a7cde1b
--- /dev/null
+++ b/tests/fsharplibrary/fsharplibrary.fsproj
@@ -0,0 +1,60 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {C7212169-BA46-413B-91CD-A32C52AD5E0D}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{F2A71F9B-5D33-465A-A702-920D77279786}
+ Library
+ fsharplibrary
+ fsharplibrary
+ Resources
+ true
+ ..\..\..\xamarin-macios\product.snk
+ MonoTouch
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG
+ prompt
+ false
+ HttpClientHandler
+ true
+ true
+
+
+
+ true
+ bin\Release
+
+ prompt
+ false
+ HttpClientHandler
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/generator/.gitignore b/tests/generator/.gitignore
new file mode 100644
index 000000000000..9ec1f99dd294
--- /dev/null
+++ b/tests/generator/.gitignore
@@ -0,0 +1,2 @@
+*.source
+*.tmpdir
diff --git a/tests/generator/Makefile b/tests/generator/Makefile
new file mode 100644
index 000000000000..766ed209ad30
--- /dev/null
+++ b/tests/generator/Makefile
@@ -0,0 +1,129 @@
+TOP=../../../xamarin-macios
+
+include $(TOP)/Make.config
+
+#
+# * Use [IOS|MAC]_TESTS for simple tests that just verify the code can compile / generate.
+# To add such a test, just add the file, and add the name of the file (without extension) to [IOS|MAC]_TESTS.
+#
+# * Use [IOS|MAC]_CUSTOM_TESTS for more advanced tests that needs more validation.
+# In this case you additionally need to add a target for the name of the test, with the
+# your test logic.
+#
+
+IOS_CURRENT_DIR=$(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions/Current
+IOS_GENERATOR = $(IOS_CURRENT_DIR)/bin/btouch /baselib:$(IOS_CURRENT_DIR)/lib/mono/2.1/monotouch.dll /unsafe /compiler:$(IOS_CURRENT_DIR)/bin/smcs
+IOS_TESTS = bug15283 bug15307 bug15799 bug16036 sof20696157 bug23041 bug27430 bug27428 bug34042 btouch-with-hyphen-in-name property-redefination-ios arrayfromhandlebug bug36457 bug39614 bug40282 bug17232 bug24078-ignore-methods-events
+IOS_CUSTOM_TESTS = forum54078 desk63279 desk79124 multiple-api-definitions1 multiple-api-definitions2 bug29493 classNameCollision bi1036 bug37527 bug27986 bug35176
+
+MAC_CURRENT_DIR=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current
+MAC_GENERATOR = $(MAC_CURRENT_DIR)/bin/bmac
+MAC_TESTS = bmac_smoke bmac-with-hyphen-in-name property-redefination-mac NSApplicationPublicEnsureMethods protocol-duplicate-abstract
+MAC_CUSTOM_TESTS = bug31788 protocol-duplicate-abstract-error protocol-duplicate-method-diff-length protocol-duplicate-method-diff-out protocol-duplicate-method-diff-type protocol-duplicate-method-diff-return
+
+ALL_TESTS =
+ifdef INCLUDE_IOS
+ALL_TESTS += $(IOS_TESTS) $(IOS_CUSTOM_TESTS)
+endif
+ifdef INCLUDE_MAC
+ALL_TESTS += $(MAC_TESTS) $(MAC_CUSTOM_TESTS)
+endif
+
+all-local:: $(ALL_TESTS)
+
+$(MAC_TESTS):
+ $(if $(V),,@echo "$@";) $(MAC_GENERATOR) -d=MONOMAC $@.cs
+ $(if $(V),,@echo "$@";) $(MAC_GENERATOR) -d=MONOMAC -d=XAMCORE_2_0 --unified-full-profile $@.cs
+ $(if $(V),,@echo "$@";) $(MAC_GENERATOR) -d=MONOMAC -d=XAMCORE_2_0 --unified-mobile-profile $@.cs
+
+$(IOS_TESTS):
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@.cs
+
+define ProtocolTestTemplate
+$(1):
+ $(if $(V),,@echo "$$@";) $(MAC_GENERATOR) -d=MONOMAC $(1).cs 2>&1 | grep BI$(2) > /dev/null
+ $(if $(V),,@echo "$$@";) $(MAC_GENERATOR) -d=MONOMAC -d=XAMCORE_2_0 --unified-full-profile $(1).cs 2>&1 | grep BI$(2) > /dev/null
+ $(if $(V),,@echo "$$@";) $(MAC_GENERATOR) -d=MONOMAC -d=XAMCORE_2_0 --unified-mobile-profile $(1).cs 2>&1 | grep BI$(2) > /dev/null
+endef
+
+$(eval $(call ProtocolTestTemplate,protocol-duplicate-abstract-error,1037))
+$(eval $(call ProtocolTestTemplate,protocol-duplicate-method-diff-length,1039))
+$(eval $(call ProtocolTestTemplate,protocol-duplicate-method-diff-out,1040))
+$(eval $(call ProtocolTestTemplate,protocol-duplicate-method-diff-type,1041))
+$(eval $(call ProtocolTestTemplate,protocol-duplicate-method-diff-return,1038))
+
+classNameCollision:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@.cs -s:classNameCollision-enum.cs -tmpdir=$@.tmpdir
+
+bug31788:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(MAC_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir $@.cs
+ @grep -q xamarin_IntPtr_objc_msgSend bug31788.tmpdir/Test/MarshalOnProperty.g.cs
+ @grep -q xamarin_IntPtr_objc_msgSend bug31788.tmpdir/Test/MarshalInProperty.g.cs
+
+desk63279:
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) desk63279A.cs desk63279B.cs
+
+desk79124:
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@.cs >/dev/null 2>&1
+ @if ! monodis $@.dll --typedef | grep WYPopoverBackgroundViewAppearance > /dev/null; then \
+ echo "error: Could not find WYPopoverBackgroundViewAppearance in generated code."; \
+ fi
+
+forum54078:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir $@.cs
+ @! grep "Type does not conform to NSCoding" forum54078.tmpdir/Test/CustomController.g.cs
+
+multiple-api-definitions1:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir $@.cs
+
+multiple-api-definitions2:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir --api=$@-a.cs --api=$@-b.cs
+
+bug29493:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir $@.cs
+ @! grep -r "static readonly IntPtr class_ptr = Class.GetHandle (\"global::" bug29493.tmpdir/Bug29493
+
+bug37527:
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@-missing-property.cs | grep "BaseType.Delegates were set but no properties could be found. Do ensure that the WrapAttribute is used on the right properties." >/dev/null 2>&1
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@-wrong-property.cs | grep "should be renamed to 'Delegate' for BaseType.Events and BaseType.Delegates to work." >/dev/null 2>&1
+
+bug27986:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir $@.cs
+ @if ! grep -r Preserve bug27986.tmpdir/bug27986 > /dev/null; then \
+ echo "error: Could not find Preserve attribute in generated code."; exit 1; \
+ fi
+ @if [ `grep -r Preserve bug27986.tmpdir/bug27986 | wc -l` -ne 28 ]; then \
+ echo "Error: Expected 28 Preserve attributes in generated code. If you modified code that generates PreserveAttributes please update the preserve count."; exit 1; \
+ fi
+
+bug35176:
+ @rm -Rf $@.tmpdir
+ @mkdir -p $@.tmpdir
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) --sourceonly:$@.source -tmpdir=$@.tmpdir $@.cs
+ @if ! grep -r Introduced bug35176.tmpdir/bug35176 > /dev/null; then \
+ echo "error: Could not find Introduced attribute in generated code."; exit 1; \
+ fi
+ @if [ `grep -r Introduced bug35176.tmpdir/bug35176 | wc -l` -ne 8 ]; then \
+ echo "Error: Expected 4 Introduced attributes in generated code."; exit 1; \
+ fi
+
+bi1036:
+ $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@.cs | grep BI1036 >/dev/null 2>&1
+
+clean-local::
+ rm -f *.dll *.source
+ rm -Rf *.tmpdir
diff --git a/tests/generator/NSApplicationPublicEnsureMethods.cs b/tests/generator/NSApplicationPublicEnsureMethods.cs
new file mode 100644
index 000000000000..9b0f3e9fc5c8
--- /dev/null
+++ b/tests/generator/NSApplicationPublicEnsureMethods.cs
@@ -0,0 +1,36 @@
+/*
+ * Errors when doing non-internal (Xamarin.Mac.dll) bindings with a weak delegate:
+ *
+ * /var/folders/d5/0m2657ws4b339b0ryh0brkhw0000gn/T/etr9ustz.vgc/Test/TestClass.g.cs(105,19): error CS0122: `AppKit.NSApplication.EnsureDelegateAssignIsNotOverwritingInternalDelegate(object, object, System.Type)' is inaccessible due to its protection level
+ * /var/folders/d5/0m2657ws4b339b0ryh0brkhw0000gn/T/etr9ustz.vgc/Test/TestClass.g.cs(133,19): error CS0122: `AppKit.NSApplication.EnsureEventAndDelegateAreNotMismatched(object, System.Type)' is inaccessible due to its protection level
+ *
+ * EnsureDelegateAssignIsNotOverwritingInternalDelegate should be marked as public, not internal
+ * EnsureEventAndDelegateAreNotMismatched should be marked as public, not internal
+ *
+ */
+using System;
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test {
+ [BaseType (typeof (NSObject), Delegates=new string [] {"WeakDelegate"}, Events=new Type [] {typeof (SharedDelegate)})]
+ public interface TestClass {
+ [Export ("delegate", ArgumentSemantic.Assign), NullAllowed]
+ NSObject WeakDelegate { get; set; }
+
+ [Wrap ("WeakDelegate")]
+ [Protocolize]
+ SharedDelegate Delegate { get; set; }
+ }
+
+ [BaseType (typeof (NSObject))]
+ [Model]
+ [Protocol]
+ public interface SharedDelegate {
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/README.md b/tests/generator/README.md
new file mode 100644
index 000000000000..62a6bea58182
--- /dev/null
+++ b/tests/generator/README.md
@@ -0,0 +1,9 @@
+Tests for the binding generator
+===============================
+
+New test
+--------
+
+* Create a C# file with the api definition.
+* Add the C# file to the Makefile, like all the other tests.
+ Remember to add it to the 'all' target.
\ No newline at end of file
diff --git a/tests/generator/arrayfromhandlebug.cs b/tests/generator/arrayfromhandlebug.cs
new file mode 100644
index 000000000000..c6aaf11c7c72
--- /dev/null
+++ b/tests/generator/arrayfromhandlebug.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+#else
+using Foundation;
+#endif
+
+namespace AudioUnit {
+ // @interface AUParameterNode : NSObject
+ [BaseType (typeof(NSObject))]
+ interface AUParameterNode
+ {
+ }
+
+ // @interface AUParameterGroup : AUParameterNode
+ [BaseType (typeof(AUParameterNode))]
+ interface AUParameterGroup : INSSecureCoding
+ {
+ [Export ("allParameters")]
+ AUParameter[] AllParameters { get; }
+ }
+
+ // @interface AUParameter : AUParameterNode
+ [BaseType (typeof(AUParameterNode))]
+ interface AUParameter : INSSecureCoding
+ {
+ }
+
+ // Commenting this out "fixes" the problem
+ [BaseType (typeof(NSObject))]
+ interface AudioUnit
+ {
+ }
+}
diff --git a/tests/generator/bi1036.cs b/tests/generator/bi1036.cs
new file mode 100644
index 000000000000..5170a7e84832
--- /dev/null
+++ b/tests/generator/bi1036.cs
@@ -0,0 +1,10 @@
+using MonoTouch.Foundation;
+
+namespace NS {
+ [BaseType (typeof (NSObject))]
+ interface Foo {
+ [Export ("foo:")]
+ [Async (ResultTypeName="Result")]
+ void Method (string arg);
+ }
+}
diff --git a/tests/generator/bmac-with-hyphen-in-name.cs b/tests/generator/bmac-with-hyphen-in-name.cs
new file mode 100644
index 000000000000..31af3b611dd5
--- /dev/null
+++ b/tests/generator/bmac-with-hyphen-in-name.cs
@@ -0,0 +1,15 @@
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+#else
+using Foundation;
+#endif
+
+namespace Test
+{
+ [BaseType (typeof (NSObject))]
+ interface TestBMACLib
+ {
+ [Export ("addTwoRows:withSecond:")]
+ int Add (int first, int second);
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bmac_smoke.cs b/tests/generator/bmac_smoke.cs
new file mode 100644
index 000000000000..5c73f7a114a9
--- /dev/null
+++ b/tests/generator/bmac_smoke.cs
@@ -0,0 +1,15 @@
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+#else
+using Foundation;
+#endif
+
+namespace Test
+{
+ [BaseType (typeof (NSObject))]
+ interface TestBMACLib
+ {
+ [Export ("addTwoRows:withSecond:")]
+ int Add (int first, int second);
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/btouch-with-hyphen-in-name.cs b/tests/generator/btouch-with-hyphen-in-name.cs
new file mode 100644
index 000000000000..e22fc9043547
--- /dev/null
+++ b/tests/generator/btouch-with-hyphen-in-name.cs
@@ -0,0 +1,15 @@
+using System.Drawing;
+using System;
+
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+using MonoTouch.ObjCRuntime;
+
+namespace Desk79124 {
+ [BaseType (typeof (UIView))]
+ public interface WYPopoverBackgroundView : IUIAppearance {
+ [Export ("glossShadowOffset", ArgumentSemantic.Assign)]
+ [Appearance]
+ SizeF GlossShadowOffset { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug15283.cs b/tests/generator/bug15283.cs
new file mode 100644
index 000000000000..d3e03a65fabd
--- /dev/null
+++ b/tests/generator/bug15283.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Drawing;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+using System.Runtime.InteropServices;
+
+namespace BindingTests
+{
+ delegate NSObject MyBlockToBind (NSObject[] keys);
+
+ [BaseType (typeof (NSObject))]
+ interface TestInterface {
+ [Export ("testMethod:")]
+ void TestMethod (MyBlockToBind myBlockToBind);
+ }
+}
+
diff --git a/tests/generator/bug15307.cs b/tests/generator/bug15307.cs
new file mode 100644
index 000000000000..af7365a53fc6
--- /dev/null
+++ b/tests/generator/bug15307.cs
@@ -0,0 +1,14 @@
+// https://bugzilla.xamarin.com/show_bug.cgi?id=15307#c3
+
+using System;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+
+namespace BindingTests {
+
+ // error BI1018: btouch: No [Export] attribute on property MonoTouch.ObjCRuntime.INativeObject.Handle
+ [BaseType (typeof (UIPageViewController))]
+ interface MyPageViewController : IUIPageViewControllerDelegate, IUIPageViewControllerDataSource {
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug15799.cs b/tests/generator/bug15799.cs
new file mode 100644
index 000000000000..2b0d28e7966a
--- /dev/null
+++ b/tests/generator/bug15799.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Drawing;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+using MonoTouch.CoreBluetooth;
+
+namespace Bug15799 {
+
+ // Device Manager
+ [BaseType (typeof (NSObject))]
+ public partial interface Foo : ICBCentralManagerDelegate, ICBPeripheralDelegate {
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug16036.cs b/tests/generator/bug16036.cs
new file mode 100644
index 000000000000..a31bcabd34a5
--- /dev/null
+++ b/tests/generator/bug16036.cs
@@ -0,0 +1,13 @@
+using MonoTouch.Foundation;
+
+namespace TestCase {
+
+ delegate void TestHandler (int result, NSError err);
+
+ [BaseType (typeof (NSObject))]
+ interface Foo {
+
+ [Async, Static, Export ("someMethod:")]
+ bool SomeMethod (TestHandler callback);
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug17232.cs b/tests/generator/bug17232.cs
new file mode 100644
index 000000000000..4d976c0fd2b2
--- /dev/null
+++ b/tests/generator/bug17232.cs
@@ -0,0 +1,34 @@
+using System;
+using MonoTouch;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+
+namespace xam.bug17232 {
+ [BaseType (typeof (NSObject))]
+ interface FieldsTest {
+
+ [Field ("MyFooFieldA", "libFoo.a")]
+ NSString FooFieldA { get; }
+
+ [Field ("MyFooFieldB", "libFoo.a")]
+ NSString FooFieldB { get; set; }
+
+ [Field ("MyBarFieldA", "Frameworks/Bar.framework/Bar")]
+ NSString BarFieldA { get; }
+
+ [Field ("MyBarFieldB", "Frameworks/Bar.framework/Bar")]
+ NSString BarFieldB { get; set; }
+
+ [Field ("MyBarFieldA", "Xyz")]
+ NSString XyzFieldA { get; }
+
+ [Field ("XyzFieldB", "Xyz")]
+ NSString XyzFieldB { get; set; }
+
+ [Field ("MyUnboundField", Constants.CoreGraphicsLibrary)]
+ NSString UnboundField { get; set; }
+
+ [Field ("MyUnboundUIKitField", "UIKit")]
+ NSString UnboundUIKitField { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug23041.cs b/tests/generator/bug23041.cs
new file mode 100644
index 000000000000..0ad1200eb032
--- /dev/null
+++ b/tests/generator/bug23041.cs
@@ -0,0 +1,10 @@
+using MonoTouch;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+
+namespace Test {
+[Model, BaseType (typeof (UIPopoverControllerDelegate))]
+[Protocol]
+public partial interface BindingMainTabBarControllerScreensHandler {
+}
+}
diff --git a/tests/generator/bug24078-ignore-methods-events.cs b/tests/generator/bug24078-ignore-methods-events.cs
new file mode 100644
index 000000000000..13c29c3ddb66
--- /dev/null
+++ b/tests/generator/bug24078-ignore-methods-events.cs
@@ -0,0 +1,42 @@
+/*
+ * Allow to ignore certain methods from the generation of events.
+ *
+ */
+using System;
+#if !XAMCORE_2_0
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.UIKit;
+#else
+using Foundation;
+using ObjCRuntime;
+using UIKit;
+#endif
+
+namespace Test {
+
+ [BaseType (typeof (NSObject),
+ Delegates=new string [] {"WeakDelegate"},
+ Events=new Type [] { typeof (UIPopoverPresentationControllerDelegate) })]
+ public partial interface TestController {
+ [Export ("delegate", ArgumentSemantic.UnsafeUnretained)]
+ NSObject WeakDelegate { get; set; }
+
+ [Wrap ("WeakDelegate")]
+ [Protocolize]
+ UIPopoverPresentationControllerDelegate Delegate { get; set; }
+ }
+
+ [Protocol, Model]
+ [BaseType (typeof (NSObject))]
+ public partial interface UIPopoverPresentationControllerDelegate {
+ [IgnoredInDelegate] // ignore this method in the c# events
+ [Export ("adaptivePresentationStyleForPresentationController:")]
+ UIModalPresentationStyle GetAdaptivePresentationStyle (UIPresentationController forPresentationController);
+
+ [Export ("adaptivePresentationStyleForPresentationController:traitCollection:"),
+ DelegateName ("AdaptivePresentationStyleWithTraitsRequested"), DefaultValue (UIModalPresentationStyle.None)]
+ UIModalPresentationStyle GetAdaptivePresentationStyle (UIPresentationController controller, UITraitCollection traitCollection);
+
+ }
+}
diff --git a/tests/generator/bug27428.cs b/tests/generator/bug27428.cs
new file mode 100644
index 000000000000..2859d9f3a517
--- /dev/null
+++ b/tests/generator/bug27428.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Drawing;
+
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+
+namespace Foo.BindingBugs
+{
+ [BaseType (typeof (NSObject))]
+ interface Widget {
+ [Export ("doSomething:atIndex:")]
+ void DoSomething (NSObject @object, int index);
+ }
+}
+
diff --git a/tests/generator/bug27430.cs b/tests/generator/bug27430.cs
new file mode 100644
index 000000000000..baf52f6c2be4
--- /dev/null
+++ b/tests/generator/bug27430.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Drawing;
+
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+
+namespace Bug27430
+{
+ delegate void SomeHandler (int @int, string @string, NSError @namespace);
+ delegate void SomeHandler2 (NSDictionary[] @switch, string[] @case, NSError @namespace);
+
+ [BaseType (typeof (NSObject))]
+ interface Widget {
+
+ [Export ("initWithTest:")]
+ IntPtr Constructor (IFooTestDelegate @delegate);
+
+ [Async (ResultTypeName = "FooResultTask")]
+ [Export ("doSomething:atIndex::::")]
+ void DoSomething (NSObject obj, string str, int i, uint @uint, SomeHandler handler);
+
+ [Async]
+ [Export ("doSomething1:atIndex::::")]
+ void DoSomething1 (NSObject @object, string @string, int @int, uint @uint, Action @delegate);
+
+ [Export ("outTest:atIndex::::")]
+ void OutTest (out NSObject @object, out string @string, out int @int, out uint @uint, Action @delegate);
+
+ [Export ("refTest:atIndex::::")]
+ void RefTest (ref NSObject @object, ref string @string, ref int @int, ref uint @uint, Action @delegate);
+
+ [Export ("RefHandlderTest:atIndex::::")]
+ void RefHandlderTest (ref NSObject @object, ref string @string, ref int @int, ref uint @uint, SomeHandler @delegate);
+
+ [Export ("PlainStringTest:atIndex::::")]
+ void PlainStringTest (NSObject @object, [PlainString] string @string, NSString @for, NSNumber @foreach, NSNumber @override);
+
+ [Export ("NullAllowedTest:atIndex::::")]
+ void NullAllowedTest ([NullAllowed] NSObject @object, [NullAllowed] string @string, [NullAllowed] NSString @for, [NullAllowed] NSNumber @foreach, [NullAllowed] NSNumber @override);
+
+ [Async]
+ [Export ("arrayTest:atIndex::::")]
+ void ArrayTest (NSObject [] @object, string [] @string, int @int, uint @uint, Action @delegate);
+
+ [Async (ResultTypeName = "ArrayResultTask")]
+ [Export ("arrayTest2:atIndex::::")]
+ void ArrayTest2 (NSObject [] @object, string [] @string, int @int, uint @uint, SomeHandler2 @delegate);
+
+ [Async]
+ [Export ("doSomethingErr:atIndex::::")]
+ void DoSomethingErrTest (NSObject @object, string @string, int @int, uint @uint, Action @delegate);
+
+ [Async (ResultTypeName = "FooResultTask2")]
+ [Export ("doSomethingErr2:atIndex::::")]
+ void DoSomethingErr2Test (NSObject @object, string @string, int @int, uint @uint, Action @delegate);
+
+ [Export ("putDelegatesSomewhere:::")]
+ void PutDelegatesTest (IFooTestDelegate @delegate, IUIPageViewControllerDelegate @namespace, int @int);
+
+ [Export ("delegate", ArgumentSemantic.Weak), NullAllowed]
+ IFooTestDelegate @delegate { get; set; }
+
+ [Export ("dont")]
+ string @string { get; set; }
+
+ [Export ("dont2")]
+ int @int { [Bind ("isDont2")] get; set; }
+
+ [Export ("dont3")]
+ UIView [] @foreach { get; [Bind ("foo3:")] set; }
+
+ [Export ("dont4")]
+ UIView [] @case {[Bind ("bar4")] get; [Bind ("foo4:")] set; }
+
+ [Export ("dont")]
+ NSArray @void { get; }
+ }
+
+ interface IFooTestDelegate { }
+
+ [Protocol, Model]
+ [BaseType (typeof (NSObject))]
+ interface FooTestDelegate {
+
+ [Export ("someFakeDelegateMethod:withDelegate:")]
+ void SomeFakeDelegateMethod (UIViewController @switch, IFooTestDelegate @delegate);
+ }
+}
+
+
diff --git a/tests/generator/bug27986.cs b/tests/generator/bug27986.cs
new file mode 100644
index 000000000000..389405374228
--- /dev/null
+++ b/tests/generator/bug27986.cs
@@ -0,0 +1,70 @@
+using System;
+
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using System.Drawing;
+
+namespace bug27986
+{
+ interface IFooProtocol { }
+
+ [Model, Protocol, Preserve (AllMembers = true)]
+ [BaseType (typeof (NSObject))]
+ interface FooProtocol {
+
+ [Preserve]
+ [Export ("doSomething:atIndex:")]
+ void DoSomething (NSObject @object, int index);
+
+ [Abstract]
+ [Preserve (Conditional = true)]
+ [Export ("doSomething:atIndex2:")]
+ void DoSomething2 (NSObject @object, int index);
+
+ [Abstract]
+ [Preserve (Conditional = true)]
+ [Export ("center")]
+ NSObject Center { get; set; }
+
+ [Preserve]
+ [Export ("center2")]
+ NSObject Center2 { get; set; }
+ }
+
+
+ [BaseType (typeof (NSObject))]
+ [Preserve (AllMembers = true)]
+ interface Widget {
+
+ [Preserve (Conditional = true)]
+ [Export ("initWithElmo:")]
+ IntPtr Constructor (uint elmo);
+
+ [Preserve]
+ [Export ("doSomething:atIndex:")]
+ void DoSomething (NSObject @object, int index);
+
+ [Preserve (Conditional = true)]
+ [Export ("center")]
+ NSObject Center { get; set; }
+
+ [Export("noCenter")]
+ PointF NoCenter { [Preserve (Conditional = true)] get; [Preserve] set; }
+
+ [Preserve]
+ [Field ("FooField", "__Internal")]
+ NSString FooField { get; }
+
+ [Field ("IntField", "__Internal")]
+ int IntField { [Preserve (Conditional = true)] get; [Preserve] set; }
+
+ [Wrap ("Center")]
+ [Preserve]
+ NSString CenterWrap { get; set; }
+
+ [Preserve (Conditional = true)]
+ [Export ("delegate")]
+ IFooProtocol Delegate { get; set; }
+ }
+}
+
diff --git a/tests/generator/bug29493.cs b/tests/generator/bug29493.cs
new file mode 100644
index 000000000000..58321e6fb6dc
--- /dev/null
+++ b/tests/generator/bug29493.cs
@@ -0,0 +1,111 @@
+using System;
+
+using MonoTouch.UIKit;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.CoreGraphics;
+
+namespace Bug29493
+{
+ [Category]
+ [BaseType (typeof(UIColor))]
+ interface UIColorExtensions
+ {
+ // +(UIColor *)jbill_messageBubbleGreenColor;
+ [Static]
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor ();
+
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor2 ();
+ }
+
+ [Category]
+ [BaseType (typeof(NSUrlSession))]
+ interface NSUrlExtensions
+ {
+ // +(UIColor *)jbill_messageBubbleGreenColor;
+ [Static]
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor ();
+
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor2 ();
+ }
+
+ [BaseType (typeof(NSObject))]
+ interface HelloKitty
+ {
+
+ }
+
+ [Category]
+ [BaseType (typeof(HelloKitty))]
+ interface HelloKittyExtensions
+ {
+ // +(UIColor *)jbill_messageBubbleGreenColor;
+ [Static]
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor ();
+
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor2 ();
+ }
+
+ [BaseType (typeof(NSObject), Name = "NSBatman")]
+ interface BecauseImBatman
+ {
+
+ }
+
+ [Category]
+ [BaseType (typeof(BecauseImBatman))]
+ interface BecauseImBatmanExtensions
+ {
+ // +(UIColor *)jbill_messageBubbleGreenColor;
+ [Static]
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor ();
+
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor2 ();
+ }
+
+ [BaseType (typeof(BecauseImBatman), Name = "NSBatman2")]
+ interface BecauseImBatman2
+ {
+
+ }
+
+ [Category]
+ [BaseType (typeof(BecauseImBatman2))]
+ interface BecauseImBatman2Extensions
+ {
+ // +(UIColor *)jbill_messageBubbleGreenColor;
+ [Static]
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor ();
+
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor2 ();
+ }
+
+ [BaseType (typeof(BecauseImBatman))]
+ interface Superman
+ {
+
+ }
+
+ [Category]
+ [BaseType (typeof(Superman))]
+ interface SupermanExtensions
+ {
+ // +(UIColor *)jbill_messageBubbleGreenColor;
+ [Static]
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor ();
+
+ [Export ("jbill_messageBubbleGreenColor")]
+ UIColor MessageBubbleGreenColor2 ();
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug31788.cs b/tests/generator/bug31788.cs
new file mode 100644
index 000000000000..049ec0132286
--- /dev/null
+++ b/tests/generator/bug31788.cs
@@ -0,0 +1,30 @@
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+#else
+using Foundation;
+#endif
+
+namespace Test
+{
+ [BaseType (typeof (NSObject))]
+ interface SimServiceConnectionManager {}
+
+ // Both these should produce the same output,
+ // both calling xamarin_IntPtr_objc_msgSend
+ [BaseType (typeof (NSObject))]
+ interface MarshalOnProperty
+ {
+ [Static]
+ [Export ("sharedConnectionManager")]
+ [MarshalNativeExceptions]
+ SimServiceConnectionManager Shared { get; }
+ }
+
+ [BaseType (typeof (NSObject))]
+ interface MarshalInProperty
+ {
+ [Static]
+ [Export ("sharedConnectionManager")]
+ SimServiceConnectionManager Shared { [MarshalNativeExceptions]get; }
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug34042.cs b/tests/generator/bug34042.cs
new file mode 100644
index 000000000000..e1dcbfad96e0
--- /dev/null
+++ b/tests/generator/bug34042.cs
@@ -0,0 +1,21 @@
+using System;
+
+using MonoTouch.UIKit;
+
+namespace Bug34042.Foo
+{
+ [BaseType (typeof(UIButton))]
+ interface FooButton
+ {
+
+ }
+}
+
+namespace Bug34042.Bar
+{
+ [BaseType (typeof(Bug34042.Foo.FooButton))]
+ interface BarButton
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug35176.cs b/tests/generator/bug35176.cs
new file mode 100644
index 000000000000..e98284ff37c1
--- /dev/null
+++ b/tests/generator/bug35176.cs
@@ -0,0 +1,29 @@
+using System;
+using MonoTouch.UIKit;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.Foundation;
+
+namespace Bug35176 {
+
+ [Introduced (PlatformName.iOS, 8,0)]
+ [Introduced (PlatformName.MacOSX, 10,10)]
+ [Protocol]
+ interface FooInterface {
+
+ [Abstract]
+ [Export ("fooView")]
+ UIView FooView { get; set; }
+
+ [Export ("BarView")]
+ UIView BarView { [Introduced (PlatformName.iOS, 9,0)] get; }
+
+ [Export ("barMember:")]
+ UIView GetBarMember (int x);
+ }
+
+ [BaseType (typeof (NSObject))]
+ interface BarObject : FooInterface
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug36457.cs b/tests/generator/bug36457.cs
new file mode 100644
index 000000000000..cea8a77dbca2
--- /dev/null
+++ b/tests/generator/bug36457.cs
@@ -0,0 +1,12 @@
+using MonoTouch.Foundation;
+
+namespace Bug {
+ delegate string ReturnsString ();
+
+ [BaseType (typeof(NSObject))]
+ interface Type
+ {
+ [Export ("returnString")]
+ ReturnsString ReturnString { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/bug37527-missing-property.cs b/tests/generator/bug37527-missing-property.cs
new file mode 100644
index 000000000000..4a9408b67fb6
--- /dev/null
+++ b/tests/generator/bug37527-missing-property.cs
@@ -0,0 +1,26 @@
+/*
+ * Errors when doing users perform a binding but the Delegate property is missing.
+ *
+ */
+using System;
+#if !XAMCORE_2_0
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test {
+ [BaseType (typeof (NSObject))]
+ [Model]
+ [Protocol]
+ public interface SharedDelegate {
+ }
+
+ [BaseType (typeof (NSObject), Delegates=new string [] {"WeakDelegate"}, Events=new Type [] {typeof (SharedDelegate)})]
+ public interface TestMissingPropertyName{
+ [Export ("delegate", ArgumentSemantic.Assign), NullAllowed]
+ NSObject WeakDelegate { get; set; }
+ }
+}
diff --git a/tests/generator/bug37527-wrong-property.cs b/tests/generator/bug37527-wrong-property.cs
new file mode 100644
index 000000000000..e7b8105e30e8
--- /dev/null
+++ b/tests/generator/bug37527-wrong-property.cs
@@ -0,0 +1,30 @@
+/*
+ * Errors when doing users perform a binding but the Delegate property does not use the correct name.
+ *
+ */
+using System;
+#if !XAMCORE_2_0
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test {
+ [BaseType (typeof (NSObject))]
+ [Model]
+ [Protocol]
+ public interface SharedDelegate {
+ }
+
+ [BaseType (typeof (NSObject), Delegates=new string [] {"WeakDelegate"}, Events=new Type [] {typeof (SharedDelegate)})]
+ public interface TestWrongPropertyName{
+ [Export ("delegate", ArgumentSemantic.Assign), NullAllowed]
+ NSObject WeakDelegate { get; set; }
+
+ [Wrap ("WeakDelegate")]
+ [Protocolize]
+ SharedDelegate TestProperty { get; set; }
+ }
+}
diff --git a/tests/generator/bug39614.cs b/tests/generator/bug39614.cs
new file mode 100644
index 000000000000..74507c89109f
--- /dev/null
+++ b/tests/generator/bug39614.cs
@@ -0,0 +1,21 @@
+using System;
+using MonoTouch.Foundation;
+
+[BaseType (typeof (NSObject))]
+public interface FooType
+ where GenType : NSObject {
+
+ [Export ("bar")]
+ GenType bar { get; set; }
+
+ [Static]
+ [Export ("fooType:value:")]
+ GenType FromFoo (string fooType, GenType value);
+
+ [Export ("initWithFoo:value:")]
+ IntPtr Constructor (string foo, GenType value);
+
+ [Export ("getBar:")]
+ GenType GetBar (string bar);
+}
+
diff --git a/tests/generator/bug40282.cs b/tests/generator/bug40282.cs
new file mode 100644
index 000000000000..7528029c9c22
--- /dev/null
+++ b/tests/generator/bug40282.cs
@@ -0,0 +1,19 @@
+using System;
+using MonoTouch.Foundation;
+
+namespace bug40282 {
+ [Internal]
+ [Protocol, Model]
+ [BaseType (typeof (NSObject))]
+ interface FooDelegateInternal {
+ [Export ("fooService:hasUInt32s:numberOfItems:forFooSession:")]
+ bool FooServiceUInt32 (int service, IntPtr data, ushort numberOfItems, int session);
+
+ [Export ("fooService:hasSInt16s:numberOfItems:forFooSession:")]
+ bool FooServiceSInt16 (int service, IntPtr data, ushort numberOfItems, int session);
+
+ [Export ("fooService:sessionDidFinish:")]
+ void FooService (int service, int session);
+ }
+}
+
diff --git a/tests/generator/classNameCollision-enum.cs b/tests/generator/classNameCollision-enum.cs
new file mode 100644
index 000000000000..29e98a92e68b
--- /dev/null
+++ b/tests/generator/classNameCollision-enum.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+#else
+using Foundation;
+#endif
+
+namespace AudioUnit {
+ [StructLayout (LayoutKind.Sequential)]
+ public struct AURecordedParameterEvent
+ {
+ public ulong hostTime;
+ public ulong address;
+ public float value;
+ }
+}
diff --git a/tests/generator/classNameCollision.cs b/tests/generator/classNameCollision.cs
new file mode 100644
index 000000000000..369c8b1155f5
--- /dev/null
+++ b/tests/generator/classNameCollision.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+#else
+using Foundation;
+#endif
+
+namespace AudioUnit {
+ [BaseType (typeof(NSObject))]
+ interface AUParameterNode
+ {
+ [Export ("tokenByAddingParameterRecordingObserver:")]
+ IntPtr TokenByAddingParameterRecordingObserver (AUParameterRecordingObserver observer);
+ }
+
+ public unsafe delegate void AUParameterRecordingObserver (int arg0, AURecordedParameterEvent arg1);
+
+ // Commenting this out "fixes" the problem
+ [BaseType (typeof(NSObject))]
+ interface AudioUnit
+ {
+ }
+}
diff --git a/tests/generator/desk63279A.cs b/tests/generator/desk63279A.cs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/generator/desk63279B.cs b/tests/generator/desk63279B.cs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/generator/desk79124.cs b/tests/generator/desk79124.cs
new file mode 100644
index 000000000000..e22fc9043547
--- /dev/null
+++ b/tests/generator/desk79124.cs
@@ -0,0 +1,15 @@
+using System.Drawing;
+using System;
+
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+using MonoTouch.ObjCRuntime;
+
+namespace Desk79124 {
+ [BaseType (typeof (UIView))]
+ public interface WYPopoverBackgroundView : IUIAppearance {
+ [Export ("glossShadowOffset", ArgumentSemantic.Assign)]
+ [Appearance]
+ SizeF GlossShadowOffset { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/forum54078.cs b/tests/generator/forum54078.cs
new file mode 100644
index 000000000000..4ad0b8d4e83f
--- /dev/null
+++ b/tests/generator/forum54078.cs
@@ -0,0 +1,10 @@
+// We test that a third-party binding inheriting from UIViewController
+// gets a proper NSCoding constructor.
+using MonoTouch.UIKit;
+
+namespace Test {
+ [BaseType (typeof (UIViewController))]
+ public interface CustomController {
+
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/multiple-api-definitions1.cs b/tests/generator/multiple-api-definitions1.cs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/generator/multiple-api-definitions2-a.cs b/tests/generator/multiple-api-definitions2-a.cs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/generator/multiple-api-definitions2-b.cs b/tests/generator/multiple-api-definitions2-b.cs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/generator/property-redefination-ios.cs b/tests/generator/property-redefination-ios.cs
new file mode 100644
index 000000000000..57a975f7372a
--- /dev/null
+++ b/tests/generator/property-redefination-ios.cs
@@ -0,0 +1,28 @@
+#if !XAMCORE_2_0
+using MonoTouch.Foundation;
+#else
+using Foundation;
+#endif
+
+namespace Test
+{
+ [BaseType (typeof (NSObject))]
+ [Protocol, Model]
+ public interface NSTextInputClient
+ {
+ [Export ("selectedRange")]
+ NSRange SelectedRange { get; }
+ }
+
+ [BaseType (typeof (NSObject))]
+ interface NSText
+ {
+ [Export ("selectedRange")]
+ NSRange SelectedRange { get; set; }
+ }
+
+ [BaseType (typeof (NSText))]
+ interface NSTextView : NSTextInputClient
+ {
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/property-redefination-mac.cs b/tests/generator/property-redefination-mac.cs
new file mode 100644
index 000000000000..1ef716bd1862
--- /dev/null
+++ b/tests/generator/property-redefination-mac.cs
@@ -0,0 +1,28 @@
+#if !XAMCORE_2_0
+using MonoMac.Foundation;
+#else
+using Foundation;
+#endif
+
+namespace Test
+{
+ [BaseType (typeof (NSObject))]
+ [Protocol, Model]
+ public interface NSTextInputClient
+ {
+ [Export ("selectedRange")]
+ NSRange SelectedRange { get; }
+ }
+
+ [BaseType (typeof (NSObject))]
+ public interface NSText
+ {
+ [Export ("selectedRange")]
+ NSRange SelectedRange { get; set; }
+ }
+
+ [BaseType (typeof (NSText))]
+ public interface NSTextView : NSTextInputClient
+ {
+ }
+}
\ No newline at end of file
diff --git a/tests/generator/protocol-duplicate-abstract-error.cs b/tests/generator/protocol-duplicate-abstract-error.cs
new file mode 100644
index 000000000000..9f635f3f5fdb
--- /dev/null
+++ b/tests/generator/protocol-duplicate-abstract-error.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test
+{
+ [Protocol]
+ public interface First
+ {
+ [Abstract]
+ [NullAllowed, Export ("identifier")]
+ string Identifier { set; }
+ }
+
+ [Protocol]
+ public interface Second {
+ [Abstract]
+ [NullAllowed, Export ("identifier")]
+ string Identifier { get; }
+ }
+
+ [BaseType (typeof (NSObject))]
+ public partial interface Derived : First, Second {
+ }
+}
+
diff --git a/tests/generator/protocol-duplicate-abstract.cs b/tests/generator/protocol-duplicate-abstract.cs
new file mode 100644
index 000000000000..891f84328fac
--- /dev/null
+++ b/tests/generator/protocol-duplicate-abstract.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test
+{
+ [Protocol]
+ public interface First
+ {
+ [Abstract]
+ [NullAllowed, Export ("identifier")]
+ string Identifier { get; set; }
+
+ [Abstract]
+ [Export ("doit")]
+ void DoIt ();
+
+ [Abstract]
+ [Export ("doit:with:more")]
+ void DoIt (int a, int b);
+ }
+
+ [Protocol]
+ public interface Second {
+ [Abstract]
+ [NullAllowed, Export ("identifier")]
+ string Identifier { get; }
+
+ [Abstract]
+ [Export ("doit")]
+ void DoIt ();
+
+ [Abstract]
+ [Export ("doit:with:more")]
+ void DoIt (int a, int b);
+ }
+
+ [BaseType (typeof (NSObject))]
+ public partial interface Derived : First, Second {
+ }
+}
+
diff --git a/tests/generator/protocol-duplicate-method-diff-length.cs b/tests/generator/protocol-duplicate-method-diff-length.cs
new file mode 100644
index 000000000000..271a64c6a976
--- /dev/null
+++ b/tests/generator/protocol-duplicate-method-diff-length.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test
+{
+ [Protocol]
+ public interface First
+ {
+ [Abstract]
+ [Export ("doit:itwith:more:")]
+ void DoIt (int a, int b, int c);
+ }
+
+ [Protocol]
+ public interface Second {
+ [Abstract]
+ [Export ("doit:itwith:more:")]
+ void DoIt (int a, int b, int c, int d);
+ }
+
+ [BaseType (typeof (NSObject))]
+ public partial interface Derived : First, Second {
+ }
+}
+
diff --git a/tests/generator/protocol-duplicate-method-diff-out.cs b/tests/generator/protocol-duplicate-method-diff-out.cs
new file mode 100644
index 000000000000..d8fdee2af2c3
--- /dev/null
+++ b/tests/generator/protocol-duplicate-method-diff-out.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test
+{
+ [Protocol]
+ public interface First
+ {
+ [Abstract]
+ [Export ("doit:withmore")]
+ void DoIt (int a, out int b);
+ }
+
+ [Protocol]
+ public interface Second {
+ [Abstract]
+ [Export ("doit:withmore")]
+ void DoIt (int a, int b);
+ }
+
+ [BaseType (typeof (NSObject))]
+ public partial interface Derived : First, Second {
+ }
+}
+
diff --git a/tests/generator/protocol-duplicate-method-diff-return.cs b/tests/generator/protocol-duplicate-method-diff-return.cs
new file mode 100644
index 000000000000..d62d3ea6e132
--- /dev/null
+++ b/tests/generator/protocol-duplicate-method-diff-return.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test
+{
+ [Protocol]
+ public interface First
+ {
+ [Abstract]
+ [Export ("doit:with:more:stuff")]
+ void DoIt (int a, int b, int c);
+ }
+
+ [Protocol]
+ public interface Second {
+ [Abstract]
+ [Export ("doit:with:more:stuff")]
+ bool DoIt (int a, int b, int c);
+ }
+
+ [BaseType (typeof (NSObject))]
+ public partial interface Derived : First, Second {
+ }
+}
+
diff --git a/tests/generator/protocol-duplicate-method-diff-type.cs b/tests/generator/protocol-duplicate-method-diff-type.cs
new file mode 100644
index 000000000000..97e3ed43ff35
--- /dev/null
+++ b/tests/generator/protocol-duplicate-method-diff-type.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if !XAMCORE_2_0
+#if MONOMAC
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+#else
+using Foundation;
+using ObjCRuntime;
+#endif
+
+namespace Test
+{
+ [Protocol]
+ public interface First
+ {
+ [Abstract]
+ [Export ("doit:with:more:")]
+ void DoIt (int a, int b, int c);
+ }
+
+ [Protocol]
+ public interface Second {
+ [Abstract]
+ [Export ("doit:with:more:")]
+ void DoIt (int a, int b, NSObject c);
+ }
+
+ [BaseType (typeof (NSObject))]
+ public partial interface Derived : First, Second {
+ }
+}
+
diff --git a/tests/generator/sof20696157.cs b/tests/generator/sof20696157.cs
new file mode 100644
index 000000000000..5bbf91ec52a1
--- /dev/null
+++ b/tests/generator/sof20696157.cs
@@ -0,0 +1,405 @@
+using MonoMac.AVFoundation;
+using MonoMac.AddressBook;
+using MonoMac.AppKit;
+using MonoMac.AudioToolbox;
+using MonoMac.AudioUnit;
+using MonoMac.AudioUnitWrapper;
+using MonoMac.Constants;
+using MonoMac.CoreAnimation;
+using MonoMac.CoreBluetooth;
+using MonoMac.CoreData;
+using MonoMac.CoreFoundation;
+using MonoMac.CoreGraphics;
+using MonoMac.CoreImage;
+using MonoMac.CoreLocation;
+using MonoMac.CoreMedia;
+using MonoMac.CoreMidi;
+using MonoMac.CoreServices;
+using MonoMac.CoreText;
+using MonoMac.CoreVideo;
+using MonoMac.CoreWlan;
+using MonoMac.Darwin;
+using MonoMac.Foundation;
+using MonoMac.GameKit;
+using MonoMac.Growl;
+using MonoMac.ImageIO;
+using MonoMac.ImageKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.OpenAL;
+using MonoMac.OpenGL;
+using MonoMac.PdfKit;
+using MonoMac.QTKit;
+using MonoMac.QuartzComposer;
+using MonoMac.QuickLook;
+using MonoMac.SceneKit;
+using MonoMac.ScriptingBridge;
+using MonoMac.Security;
+using MonoMac.StoreKit;
+using MonoMac.WebKit;
+using MonoTouch;
+using MonoTouch.AVFoundation;
+using MonoTouch.Accelerate;
+using MonoTouch.Accounts;
+using MonoTouch.AdSupport;
+using MonoTouch.AddressBook;
+using MonoTouch.AddressBookUI;
+using MonoTouch.AssetsLibrary;
+using MonoTouch.AudioToolbox;
+using MonoTouch.AudioUnit;
+using MonoTouch.AudioUnitWrapper;
+using MonoTouch.CoreAnimation;
+using MonoTouch.CoreBluetooth;
+using MonoTouch.CoreData;
+using MonoTouch.CoreFoundation;
+using MonoTouch.CoreGraphics;
+using MonoTouch.CoreImage;
+using MonoTouch.CoreLocation;
+using MonoTouch.CoreMedia;
+using MonoTouch.CoreMidi;
+using MonoTouch.CoreMotion;
+using MonoTouch.CoreServices;
+using MonoTouch.CoreTelephony;
+using MonoTouch.CoreText;
+using MonoTouch.CoreVideo;
+using MonoTouch.EventKit;
+using MonoTouch.EventKitUI;
+using MonoTouch.ExternalAccessory;
+using MonoTouch.Foundation;
+using MonoTouch.GLKit;
+using MonoTouch.GameController;
+using MonoTouch.GameKit;
+using MonoTouch.ImageIO;
+using MonoTouch.JavaScriptCore;
+using MonoTouch.MapKit;
+using MonoTouch.MediaAccessibility;
+using MonoTouch.MediaPlayer;
+using MonoTouch.MediaToolbox;
+using MonoTouch.MessageUI;
+using MonoTouch.MobileCoreServices;
+using MonoTouch.MultipeerConnectivity;
+using MonoTouch.NewsstandKit;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.OpenGLES;
+using MonoTouch.PassKit;
+using MonoTouch.QuickLook;
+using MonoTouch.Registrar;
+using MonoTouch.SafariServices;
+using MonoTouch.Security;
+using MonoTouch.Social;
+using MonoTouch.SpriteKit;
+using MonoTouch.StoreKit;
+using MonoTouch.SystemConfiguration;
+using MonoTouch.Twitter;
+using MonoTouch.UIKit;
+using MonoTouch.iAd;
+using OpenTK;
+using System.Drawing;
+using System.Reflection.Emit;
+namespace Test {
+ [Protocol] interface C1 : ICFType {}
+ [Protocol] interface C2 : INativeObject {}
+ [Protocol] interface C3 : IUITextInputTraits {}
+ [Protocol] interface C4 : IUIGuidedAccessRestrictionDelegate {}
+ [Protocol] interface C5 : IGLKNamedEffect {}
+ [Protocol] interface C6 : IGLKViewDelegate {}
+ [Protocol] interface C7 : IGLKViewControllerDelegate {}
+ [Protocol] interface C8 : IMPMediaPickerControllerDelegate {}
+ [Protocol] interface C9 : IMFMailComposeViewControllerDelegate {}
+ [Protocol] interface C10 : IMFMessageComposeViewControllerDelegate {}
+ [Protocol] interface C11 : INSTextAttachmentContainer {}
+ [Protocol] interface C12 : INSTextStorageDelegate {}
+ [Protocol] interface C13 : INSLayoutManagerDelegate {}
+ [Protocol] interface C14 : IUIAccelerometerDelegate {}
+ [Protocol] interface C15 : IUIActionSheetDelegate {}
+ [Protocol] interface C16 : IUIActivityItemSource {}
+ [Protocol] interface C17 : IUIAlertViewDelegate {}
+ [Protocol] interface C18 : IUIAppearance {}
+ [Protocol] interface C19 : IUIStateRestoring {}
+ [Protocol] interface C20 : IUIApplicationDelegate {}
+ [Protocol] interface C21 : IUICollectionViewSource {}
+ [Protocol] interface C22 : IUICollectionViewDataSource {}
+ [Protocol] interface C23 : IUICollectionViewDelegate {}
+ [Protocol] interface C24 : IUICollectionViewDelegateFlowLayout {}
+ [Protocol] interface C25 : IUICollisionBehaviorDelegate {}
+ [Protocol] interface C26 : IUIDynamicAnimatorDelegate {}
+ [Protocol] interface C27 : IUIDynamicItem {}
+ [Protocol] interface C28 : IUIGestureRecognizerDelegate {}
+ [Protocol] interface C29 : IUITextInputTokenizer {}
+ [Protocol] interface C30 : IUITextInputDelegate {}
+ [Protocol] interface C31 : IUIBarPositioning {}
+ [Protocol] interface C32 : IUIBarPositioningDelegate {}
+ [Protocol] interface C33 : IUIDocumentInteractionControllerDelegate {}
+ [Protocol] interface C34 : IUIImagePickerControllerDelegate {}
+ [Protocol] interface C35 : IUINavigationBarDelegate {}
+ [Protocol] interface C36 : IUINavigationControllerDelegate {}
+ [Protocol] interface C37 : IUIPageViewControllerDelegate {}
+ [Protocol] interface C38 : IUIPageViewControllerDataSource {}
+ [Protocol] interface C39 : IUIPickerViewDelegate {}
+ [Protocol] interface C40 : IUIPickerViewDataSource {}
+ [Protocol] interface C41 : IUIScrollViewDelegate {}
+ [Protocol] interface C42 : IUISearchBarDelegate {}
+ [Protocol] interface C43 : IUISearchDisplayDelegate {}
+ [Protocol] interface C44 : IUITabBarDelegate {}
+ [Protocol] interface C45 : IUITabBarControllerDelegate {}
+ [Protocol] interface C46 : IUITableViewDataSource {}
+ [Protocol] interface C47 : IUITableViewDelegate {}
+ [Protocol] interface C48 : IUITextFieldDelegate {}
+ [Protocol] interface C49 : IUITextViewDelegate {}
+ [Protocol] interface C50 : IUIToolbarDelegate {}
+ [Protocol] interface C51 : IUIVideoEditorControllerDelegate {}
+ [Protocol] interface C52 : IUIViewControllerContextTransitioning {}
+ [Protocol] interface C53 : IUIViewControllerAnimatedTransitioning {}
+ [Protocol] interface C54 : IUIViewControllerInteractiveTransitioning {}
+ [Protocol] interface C55 : IUIViewControllerTransitioningDelegate {}
+ [Protocol] interface C57 : IUIViewControllerTransitionCoordinatorContext {}
+ [Protocol] interface C58 : IUIViewControllerTransitionCoordinator {}
+ [Protocol] interface C59 : IUIWebViewDelegate {}
+ [Protocol] interface C60 : IUISplitViewControllerDelegate {}
+ [Protocol] interface C61 : IUIPopoverControllerDelegate {}
+ [Protocol] interface C62 : IUIPrintInteractionControllerDelegate {}
+ [Protocol] interface C63 : IUILayoutSupport {}
+ [Protocol] interface C64 : IMKAnnotation {}
+ [Protocol] interface C65 : IMKOverlay {}
+ [Protocol] interface C66 : IMKMapViewDelegate {}
+ [Protocol] interface C67 : IMKReverseGeocoderDelegate {}
+ [Protocol] interface C68 : IMKLocalSearch {}
+ [Protocol] interface C69 : IMKLocalSearchRequest {}
+ [Protocol] interface C70 : IMKLocalSearchResponse {}
+ [Protocol] interface C71 : IABNewPersonViewControllerDelegate {}
+ [Protocol] interface C72 : IABPeoplePickerNavigationControllerDelegate {}
+ [Protocol] interface C73 : IABPersonViewControllerDelegate {}
+ [Protocol] interface C74 : IABUnknownPersonViewControllerDelegate {}
+ [Protocol] interface C75 : IEAAccessoryDelegate {}
+ [Protocol] interface C76 : IADBannerViewDelegate {}
+ [Protocol] interface C77 : IADInterstitialAdDelegate {}
+ [Protocol] interface C78 : IEKEventViewDelegate {}
+ [Protocol] interface C79 : IEKEventEditViewDelegate {}
+ [Protocol] interface C80 : IEKCalendarChooserDelegate {}
+ [Protocol] interface C81 : IPKAddPassesViewControllerDelegate {}
+ [Protocol] interface C82 : ISKPhysicsContactDelegate {}
+ [Protocol] interface C83 : IMCSessionDelegate {}
+ [Protocol] interface C84 : IMCNearbyServiceAdvertiserDelegate {}
+ [Protocol] interface C85 : IMCNearbyServiceBrowserDelegate {}
+ [Protocol] interface C86 : IMCBrowserViewControllerDelegate {}
+ [Protocol] interface C87 : IMCAdvertiserAssistantDelegate {}
+ [Protocol] interface C88 : IAVAudioPlayerDelegate {}
+ [Protocol] interface C89 : IAVAudioRecorderDelegate {}
+ [Protocol] interface C90 : IAVAudioSessionDelegate {}
+ [Protocol] interface C91 : IAVAssetResourceLoaderDelegate {}
+ [Protocol] interface C92 : IAVVideoCompositing {}
+ [Protocol] interface C93 : IAVVideoCompositionValidationHandling {}
+ [Protocol] interface C94 : IAVCaptureVideoDataOutputSampleBufferDelegate {}
+ [Protocol] interface C95 : IAVCaptureAudioDataOutputSampleBufferDelegate {}
+ [Protocol] interface C96 : IAVCaptureFileOutputRecordingDelegate {}
+ [Protocol] interface C97 : IAVCaptureMetadataOutputObjectsDelegate {}
+ [Protocol] interface C98 : IAVPlayerItemOutputPullDelegate {}
+ [Protocol] interface C99 : IAVPlayerItemOutputPushDelegate {}
+ [Protocol] interface C100 : IAVPlayerItemLegibleOutputPushDelegate {}
+ [Protocol] interface C101 : IAVAsynchronousKeyValueLoading {}
+ [Protocol] interface C102 : IAVSpeechSynthesizerDelegate {}
+ [Protocol] interface C103 : ICAMediaTiming {}
+ [Protocol] interface C104 : ICALayerDelegate {}
+ [Protocol] interface C105 : ICAAction {}
+ [Protocol] interface C106 : ICBCentralManagerDelegate {}
+ [Protocol] interface C107 : ICBPeripheralDelegate {}
+ [Protocol] interface C108 : ICBPeripheralManagerDelegate {}
+ [Protocol] interface C109 : INSFetchedResultsControllerDelegate {}
+ [Protocol] interface C110 : INSFetchedResultsSectionInfo {}
+ [Protocol] interface C111 : INSCacheDelegate {}
+ [Protocol] interface C112 : INSCoding {}
+ [Protocol] interface C113 : INSSecureCoding {}
+ [Protocol] interface C114 : INSCopying {}
+ [Protocol] interface C115 : INSMutableCopying {}
+ [Protocol] interface C116 : INSKeyedArchiverDelegate {}
+ [Protocol] interface C117 : INSKeyedUnarchiverDelegate {}
+ [Protocol] interface C118 : INSMetadataQueryDelegate {}
+ [Protocol] interface C119 : INSUrlConnectionDelegate {}
+ [Protocol] interface C120 : INSUrlConnectionDownloadDelegate {}
+ [Protocol] interface C121 : INSUrlSessionDelegate {}
+ [Protocol] interface C122 : INSUrlSessionTaskDelegate {}
+ [Protocol] interface C123 : INSUrlSessionDataDelegate {}
+ [Protocol] interface C124 : INSUrlSessionDownloadDelegate {}
+ [Protocol] interface C125 : INSStreamDelegate {}
+ [Protocol] interface C126 : INSNetServiceDelegate {}
+ [Protocol] interface C127 : INSNetServiceBrowserDelegate {}
+ [Protocol] interface C128 : INSPortDelegate {}
+ [Protocol] interface C129 : INSMachPortDelegate {}
+ [Protocol] interface C130 : INSFileManagerDelegate {}
+ [Protocol] interface C131 : INSFilePresenter {}
+ [Protocol] interface C132 : IGKPeerPickerControllerDelegate {}
+ [Protocol] interface C133 : IGKVoiceChatClient {}
+ [Protocol] interface C134 : IGKSessionDelegate {}
+ [Protocol] interface C135 : IGKLeaderboardViewControllerDelegate {}
+ [Protocol] interface C136 : IGKMatchDelegate {}
+ [Protocol] interface C137 : IGKMatchmakerViewControllerDelegate {}
+ [Protocol] interface C138 : IGKAchievementViewControllerDelegate {}
+ [Protocol] interface C139 : IGKFriendRequestComposeViewControllerDelegate {}
+ [Protocol] interface C140 : IGKTurnBasedEventHandlerDelegate {}
+ [Protocol] interface C141 : IGKTurnBasedMatchmakerViewControllerDelegate {}
+ [Protocol] interface C142 : IGKGameCenterControllerDelegate {}
+ [Protocol] interface C143 : IGKChallengeEventHandlerDelegate {}
+ [Protocol] interface C144 : IGKLocalPlayerListener {}
+ [Protocol] interface C145 : IGKChallengeListener {}
+ [Protocol] interface C146 : IGKInviteEventListener {}
+ [Protocol] interface C147 : IGKTurnBasedEventListener {}
+ [Protocol] interface C148 : IQLPreviewControllerDataSource {}
+ [Protocol] interface C149 : IQLPreviewControllerDelegate {}
+ [Protocol] interface C150 : IQLPreviewItem {}
+ [Protocol] interface C151 : ISKPaymentTransactionObserver {}
+ [Protocol] interface C152 : ISKRequestDelegate {}
+ [Protocol] interface C153 : ISKProductsRequestDelegate {}
+ [Protocol] interface C154 : ISKStoreProductViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M1 : ICFType {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M2 : INativeObject {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M3 : IUITextInputTraits {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M4 : IUIGuidedAccessRestrictionDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M5 : IGLKNamedEffect {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M6 : IGLKViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M7 : IGLKViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M8 : IMPMediaPickerControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M9 : IMFMailComposeViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M10 : IMFMessageComposeViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M11 : INSTextAttachmentContainer {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M12 : INSTextStorageDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M13 : INSLayoutManagerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M14 : IUIAccelerometerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M15 : IUIActionSheetDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M16 : IUIActivityItemSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M17 : IUIAlertViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M18 : IUIAppearance {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M19 : IUIStateRestoring {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M20 : IUIApplicationDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M21 : IUICollectionViewSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M22 : IUICollectionViewDataSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M23 : IUICollectionViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M24 : IUICollectionViewDelegateFlowLayout {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M25 : IUICollisionBehaviorDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M26 : IUIDynamicAnimatorDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M27 : IUIDynamicItem {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M28 : IUIGestureRecognizerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M29 : IUITextInputTokenizer {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M30 : IUITextInputDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M31 : IUIBarPositioning {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M32 : IUIBarPositioningDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M33 : IUIDocumentInteractionControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M34 : IUIImagePickerControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M35 : IUINavigationBarDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M36 : IUINavigationControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M37 : IUIPageViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M38 : IUIPageViewControllerDataSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M39 : IUIPickerViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M40 : IUIPickerViewDataSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M41 : IUIScrollViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M42 : IUISearchBarDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M43 : IUISearchDisplayDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M44 : IUITabBarDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M45 : IUITabBarControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M46 : IUITableViewDataSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M47 : IUITableViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M48 : IUITextFieldDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M49 : IUITextViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M50 : IUIToolbarDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M51 : IUIVideoEditorControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M52 : IUIViewControllerContextTransitioning {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M53 : IUIViewControllerAnimatedTransitioning {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M54 : IUIViewControllerInteractiveTransitioning {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M55 : IUIViewControllerTransitioningDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M57 : IUIViewControllerTransitionCoordinatorContext {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M58 : IUIViewControllerTransitionCoordinator {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M59 : IUIWebViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M60 : IUISplitViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M61 : IUIPopoverControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M62 : IUIPrintInteractionControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M63 : IUILayoutSupport {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M64 : IMKAnnotation {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M65 : IMKOverlay {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M66 : IMKMapViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M67 : IMKReverseGeocoderDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M68 : IMKLocalSearch {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M69 : IMKLocalSearchRequest {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M70 : IMKLocalSearchResponse {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M71 : IABNewPersonViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M72 : IABPeoplePickerNavigationControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M73 : IABPersonViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M74 : IABUnknownPersonViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M75 : IEAAccessoryDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M76 : IADBannerViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M77 : IADInterstitialAdDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M78 : IEKEventViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M79 : IEKEventEditViewDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M80 : IEKCalendarChooserDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M81 : IPKAddPassesViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M82 : ISKPhysicsContactDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M83 : IMCSessionDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M84 : IMCNearbyServiceAdvertiserDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M85 : IMCNearbyServiceBrowserDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M86 : IMCBrowserViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M87 : IMCAdvertiserAssistantDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M88 : IAVAudioPlayerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M89 : IAVAudioRecorderDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M90 : IAVAudioSessionDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M91 : IAVAssetResourceLoaderDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M92 : IAVVideoCompositing {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M93 : IAVVideoCompositionValidationHandling {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M94 : IAVCaptureVideoDataOutputSampleBufferDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M95 : IAVCaptureAudioDataOutputSampleBufferDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M96 : IAVCaptureFileOutputRecordingDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M97 : IAVCaptureMetadataOutputObjectsDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M98 : IAVPlayerItemOutputPullDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M99 : IAVPlayerItemOutputPushDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M100 : IAVPlayerItemLegibleOutputPushDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M101 : IAVAsynchronousKeyValueLoading {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M102 : IAVSpeechSynthesizerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M103 : ICAMediaTiming {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M104 : ICALayerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M105 : ICAAction {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M106 : ICBCentralManagerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M107 : ICBPeripheralDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M108 : ICBPeripheralManagerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M109 : INSFetchedResultsControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M110 : INSFetchedResultsSectionInfo {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M111 : INSCacheDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M112 : INSCoding {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M113 : INSSecureCoding {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M114 : INSCopying {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M115 : INSMutableCopying {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M116 : INSKeyedArchiverDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M117 : INSKeyedUnarchiverDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M118 : INSMetadataQueryDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M119 : INSUrlConnectionDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M120 : INSUrlConnectionDownloadDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M121 : INSUrlSessionDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M122 : INSUrlSessionTaskDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M123 : INSUrlSessionDataDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M124 : INSUrlSessionDownloadDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M125 : INSStreamDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M126 : INSNetServiceDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M127 : INSNetServiceBrowserDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M128 : INSPortDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M129 : INSMachPortDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M130 : INSFileManagerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M131 : INSFilePresenter {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M132 : IGKPeerPickerControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M133 : IGKVoiceChatClient {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M134 : IGKSessionDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M135 : IGKLeaderboardViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M136 : IGKMatchDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M137 : IGKMatchmakerViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M138 : IGKAchievementViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M139 : IGKFriendRequestComposeViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M140 : IGKTurnBasedEventHandlerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M141 : IGKTurnBasedMatchmakerViewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M142 : IGKGameCenterControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M143 : IGKChallengeEventHandlerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M144 : IGKLocalPlayerListener {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M145 : IGKChallengeListener {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M146 : IGKInviteEventListener {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M147 : IGKTurnBasedEventListener {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M148 : IQLPreviewControllerDataSource {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M149 : IQLPreviewControllerDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M150 : IQLPreviewItem {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M151 : ISKPaymentTransactionObserver {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M152 : ISKRequestDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M153 : ISKProductsRequestDelegate {}
+ [Protocol] [BaseType (typeof (NSObject))] interface M154 : ISKStoreProductViewControllerDelegate {}
+}
diff --git a/tests/generator/sof20696157.sh b/tests/generator/sof20696157.sh
new file mode 100644
index 000000000000..e7cad05194f2
--- /dev/null
+++ b/tests/generator/sof20696157.sh
@@ -0,0 +1,6 @@
+MONO_PATH=/Developer/MonoTouch/usr/lib/mono/2.1/ monodis /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll > monotouch.il
+for n in `grep [.]namespace *.il | sort | uniq | sed 's/.namespace //'`; do echo "using $n;"; done > sof20696157.cs
+echo "namespace Test {" >> sof20696157.cs
+C=1; for i in `grep "[.]class interface public" *.il | sed 's/.* //'`; do echo -e "\t[Protocol] interface C$C : $i {}"; let C=$C+1; done >> sof20696157.cs
+C=1; for i in `grep "[.]class interface public" *.il | sed 's/.* //'`; do echo -e "\t[Protocol] [BaseType (typeof (NSObject))] interface M$C : $i {}"; let C=$C+1; done >> sof20696157.cs
+echo "}" >> sof20696157.cs
\ No newline at end of file
diff --git a/tests/link all/AppDelegate.cs b/tests/link all/AppDelegate.cs
new file mode 100644
index 000000000000..06a94bca4831
--- /dev/null
+++ b/tests/link all/AppDelegate.cs
@@ -0,0 +1,53 @@
+#if !__WATCHOS__
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+#if XAMCORE_2_0
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+using MonoTouch.NUnit.UI;
+
+namespace LinkAll
+{
+ // The UIApplicationDelegate for the application. This class is responsible for launching the
+ // User Interface of the application, as well as listening (and optionally responding) to
+ // application events from iOS.
+ [Register ("AppDelegate")]
+ public partial class AppDelegate : UIApplicationDelegate
+ {
+ // class-level declarations
+ UIWindow window;
+ TouchRunner runner;
+
+ //
+ // This method is invoked when the application has loaded and is ready to run. In this
+ // method you should instantiate the window, load the UI into it and then make the window
+ // visible.
+ //
+ // You have 17 seconds to return from this method, or iOS will terminate your application.
+ //
+ public override bool FinishedLaunching (UIApplication app, NSDictionary options)
+ {
+ // create a new window instance based on the screen size
+ window = new UIWindow (UIScreen.MainScreen.Bounds);
+ runner = new TouchRunner (window);
+
+ // register every tests included in the main application/assembly
+ runner.Add (System.Reflection.Assembly.GetExecutingAssembly ());
+ runner.Add (typeof (BundledResources.ResourcesTest).Assembly);
+
+ window.RootViewController = new UINavigationController (runner.GetViewController ());
+
+ // make the window visible
+ window.MakeKeyAndVisible ();
+
+ return true;
+ }
+ }
+}
+#endif // !__WATCHOS__
diff --git a/tests/link all/AttributeTest.cs b/tests/link all/AttributeTest.cs
new file mode 100644
index 000000000000..c72cd763d4c5
--- /dev/null
+++ b/tests/link all/AttributeTest.cs
@@ -0,0 +1,187 @@
+//
+// Link All attribute-related Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013-2016 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+
+using NUnit.Framework;
+
+[assembly: Debuggable (DebuggableAttribute.DebuggingModes.Default)]
+
+[assembly: LinkAll.Attributes.CustomAttributeArray (typeof (LinkAll.Attributes.CustomTypeA))]
+[assembly: LinkAll.Attributes.CustomAttribute (typeof (LinkAll.Attributes.CustomType))]
+
+namespace LinkAll.Attributes {
+
+ // the linker removes those attributes on release builds but must keep them in debug builds
+ [DebuggerDisplay ("value")]
+ [DebuggerNonUserCode]
+ [DebuggerStepThrough]
+ [DebuggerTypeProxy ("")]
+ [DebuggerVisualizer ("")]
+ class FullyDecorated {
+
+ [DebuggerHidden]
+ [DebuggerStepperBoundary]
+ public FullyDecorated ()
+ {
+ }
+
+ [DebuggerBrowsable (DebuggerBrowsableState.Collapsed)]
+ public int Property { get; set; }
+ }
+
+ public class CustomAttributeArray : Attribute {
+ readonly Type[] _types;
+
+ public CustomAttributeArray (params Type[] types)
+ {
+ _types = types;
+ }
+ }
+
+ public class CustomTypeA {
+ }
+
+ public class CustomAttribute : Attribute {
+ readonly Type _type;
+
+ public CustomAttribute (Type type)
+ {
+ _type = type;
+ }
+ }
+
+ public class CustomType {
+ }
+
+ [FileIOPermission (SecurityAction.LinkDemand, AllLocalFiles = FileIOPermissionAccess.AllAccess)]
+ public class SecurityDeclarationDecoratedUserCode {
+
+ [FileIOPermission (SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.NoAccess)]
+ static public bool Check ()
+ {
+ return true;
+ }
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class AttributeTest {
+
+ [Test]
+ public void DebugAssemblyAttributes ()
+ {
+ bool result = false;
+ foreach (object ca in typeof(FullyDecorated).Assembly.GetCustomAttributes (false)) {
+ if (ca is DebuggableAttribute)
+ result = true;
+ }
+#if DEBUG
+ Assert.True (result, "DebuggableAttribute");
+#else
+ Assert.False (result, "DebuggableAttribute");
+#endif
+ }
+
+ [Test]
+ public void DebugTypeAttributes ()
+ {
+ var ca = typeof(FullyDecorated).GetCustomAttributes (false);
+#if DEBUG
+ Assert.That (ca.Length, Is.EqualTo (5), "Debug attributes in debug mode");
+#else
+ Assert.That (ca.Length, Is.EqualTo (0), "no debug attribute in release mode");
+#endif
+ }
+
+ [Test]
+ public void DebugConstructorAttributes ()
+ {
+ var ca = typeof(FullyDecorated).GetConstructor (Type.EmptyTypes).GetCustomAttributes (false);
+#if DEBUG
+ Assert.That (ca.Length, Is.EqualTo (2), "Debug attributes in debug mode");
+#else
+ Assert.That (ca.Length, Is.EqualTo (0), "No debug attribute in release mode");
+#endif
+ }
+
+ [Test]
+ public void DebugPropertyAttributes ()
+ {
+ // Ensure the linker won't remove them. Note: we do not want to use [Preserve]
+ // since it wculd change how the linker process them (and the attributes)
+ var c = new FullyDecorated ();
+ c.Property = 1;
+
+ bool result = false;
+ foreach (object ca in typeof (FullyDecorated).GetProperty ("Property").GetCustomAttributes (false)) {
+ if (ca is DebuggerBrowsableAttribute)
+ result = true;
+ }
+#if DEBUG
+ Assert.True (result, "DebuggerBrowsable");
+#else
+ Assert.False (result, "DebuggerBrowsable");
+#endif
+ }
+
+ [Test]
+ public void DebuggerTypeProxy_24203 ()
+ {
+ var d = new Dictionary () { { "key", 0 } };
+ Assert.NotNull (d); // just to be 100% sure it won't be linked away (with the attribute we'll be looking for)
+ var proxy = Type.GetType ("System.Collections.Generic.Mscorlib_DictionaryDebugView`2, mscorlib");
+#if DEBUG
+ Assert.NotNull (proxy, "proxy");
+ // having the type is nice, but it must not be empty to be useful
+ Assert.That (proxy.GetConstructors ().Length, Is.GreaterThan (0), "constructors");
+ Assert.That (proxy.GetProperties ().Length, Is.GreaterThan (0), "properties");
+#else
+ Assert.Null (proxy, "proxy");
+#endif
+ }
+
+ [Test]
+ public void CustomAttributesWithTypes ()
+ {
+ var assembly = GetType ().Assembly;
+ var ta = assembly.GetCustomAttributes ();
+ Assert.That (ta.Count (), Is.EqualTo (1), "Type[]");
+ Assert.NotNull (Type.GetType ("LinkAll.Attributes.CustomTypeA"), "CustomTypeA");
+
+ var t = assembly.GetCustomAttributes();
+ Assert.That (t.Count (), Is.EqualTo (1), "Type");
+ Assert.NotNull (Type.GetType ("LinkAll.Attributes.CustomType"), "CustomType");
+ }
+
+ [Test]
+ public void SecurityDeclaration ()
+ {
+ // note: security declarations != custom attributes
+ // we ensure that we can create the type / call the code
+ Assert.True (SecurityDeclarationDecoratedUserCode.Check (), "call");
+ // we ensure that both the permission and the flag are NOT part of the final/linked binary (link all removes security declarations)
+ Assert.Null (Type.GetType ("System.Security.Permissions.FileIOPermissionAttribute, mscorlib"), "FileIOPermissionAttribute");
+ Assert.Null (Type.GetType ("System.Security.Permissions.FileIOPermissionAccess, mscorlib"), "FileIOPermissionAccess");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/CalendarTest.cs b/tests/link all/CalendarTest.cs
new file mode 100644
index 000000000000..e0621e8fa21e
--- /dev/null
+++ b/tests/link all/CalendarTest.cs
@@ -0,0 +1,42 @@
+// Copyright 2013 Xamarin Inc. All rights reserved.
+
+using System;
+using System.Globalization;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Calendars {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class CalendarTest {
+
+ // application *MUST* be build with I18N.MidEast and I18N.Other (Thai)
+
+ [Test]
+ public void UmAlQura ()
+ {
+ var ci = CultureInfo.GetCultureInfo ("ar");
+ Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.UmAlQuraCalendar"), "Calendar");
+ }
+
+ [Test]
+ public void Hijri ()
+ {
+ var ci = CultureInfo.GetCultureInfo ("ps");
+ Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.HijriCalendar"), "Calendar");
+ }
+
+ [Test]
+ public void ThaiBuddhist ()
+ {
+ var ci = CultureInfo.GetCultureInfo ("th");
+ Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.ThaiBuddhistCalendar"), "Calendar");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/ClassLayoutTest.cs b/tests/link all/ClassLayoutTest.cs
new file mode 100644
index 000000000000..61f60900c00b
--- /dev/null
+++ b/tests/link all/ClassLayoutTest.cs
@@ -0,0 +1,115 @@
+//
+// Link All [Regression] Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Runtime.InteropServices;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Layout {
+
+ class DefaultClass {
+ public int never_used; // the linker will remove this
+ public int used;
+ }
+
+ [StructLayout (LayoutKind.Auto)]
+ class AutoClass {
+ public int never_used; // the linker will remove this
+ public int used;
+ }
+
+ [StructLayout (LayoutKind.Sequential)]
+ class SequentialClass {
+ public int never_used; // the linker MUST NOT remove this
+ public int used;
+ }
+
+ [StructLayout (LayoutKind.Explicit)]
+ class ExplicitClass {
+ [FieldOffset (0)]
+ public int never_used; // the linker could remove this
+ [FieldOffset (4)]
+ public int used;
+ [FieldOffset (8)]
+ public int never_ever_used; // the linker MUST NOT remove this
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class ClassLayoutTest {
+
+ [Test]
+ public void DefaultLayoutClass () // auto
+ {
+ DefaultClass c = new DefaultClass ();
+ c.used = 1;
+ // can't ask SizeOf on Auto
+ var t = typeof (DefaultClass);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (1), "Length");
+ Assert.That (fields [0].Name, Is.EqualTo ("used"), "Name");
+
+ Assert.True (t.IsAutoLayout, "IsAutoLayout");
+ Assert.False (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.False (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+
+ [Test]
+ public void AutoLayoutClass ()
+ {
+ AutoClass c = new AutoClass ();
+ c.used = 1;
+ // can't ask SizeOf on Auto
+ var t = typeof (AutoClass);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (1), "Length");
+ Assert.That (fields [0].Name, Is.EqualTo ("used"), "Name");
+
+ Assert.True (t.IsAutoLayout, "IsAutoLayout");
+ Assert.False (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.False (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+
+ [Test]
+ public void LayoutSequential ()
+ {
+ SequentialClass c = new SequentialClass ();
+ c.used = 1;
+ Assert.That (Marshal.SizeOf (c), Is.EqualTo (8), "2 fields");
+ var t = typeof (SequentialClass);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (2), "Length");
+
+ Assert.False (t.IsAutoLayout, "IsAutoLayout");
+ Assert.False (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.True (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+
+ [Test]
+ public void ExplicitLayout ()
+ {
+ ExplicitClass c = new ExplicitClass ();
+ c.used = 1;
+ Assert.That (Marshal.SizeOf (c), Is.GreaterThanOrEqualTo (12), "3 fields");
+ var t = typeof (ExplicitClass);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (3), "Length");
+
+ Assert.False (t.IsAutoLayout, "IsAutoLayout");
+ Assert.True (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.False (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/DataContractTest.cs b/tests/link all/DataContractTest.cs
new file mode 100644
index 000000000000..753ba3c4f2f9
--- /dev/null
+++ b/tests/link all/DataContractTest.cs
@@ -0,0 +1,82 @@
+//
+// Link All Data Contract Serialization Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Xml;
+
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+
+using NUnit.Framework;
+
+namespace LinkAll.Serialization.DataContract {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class DataContractTest {
+
+ // test case from: https://bugzilla.xamarin.com/show_bug.cgi?id=11135 (public bug)
+
+ // You also need to add custom types as '[KnownType(typeof(CustomType))]' attributes
+ public static string ToXml (T obj)
+ {
+ var sb = new StringBuilder();
+ using (var x = XmlWriter.Create (sb, new XmlWriterSettings ())) {
+ var s = new DataContractSerializer (typeof (T));
+ s.WriteObject(x, obj);
+ }
+ return sb.ToString();
+ }
+
+ public static T FromXml (string xml)
+ {
+ using (var r = XmlReader.Create (new StringReader (xml))) {
+ var s = new DataContractSerializer (typeof (T));
+ return (T) s.ReadObject (r);
+ }
+ }
+
+ [DataContract (Namespace = "mb")]
+ public class TestClass
+ {
+ public TestClass (SomeTypes types)
+ {
+ Types = types;
+ }
+
+ [DataMember]
+ public SomeTypes Types { get; set; }
+ }
+
+ [DataContract (Namespace = "mb")][Flags]
+ public enum SomeTypes {
+ [Preserve (AllMembers = true)][EnumMember] None = 0,
+ [Preserve (AllMembers = true)][EnumMember] Image = 1,
+ [Preserve (AllMembers = true)][EnumMember] Audio = 2,
+ [Preserve (AllMembers = true)][EnumMember] Video = 4,
+ [Preserve (AllMembers = true)][EnumMember] Document = 8
+ }
+
+ [Test]
+ public void Flags ()
+ {
+ var t1 = new TestClass (SomeTypes.Audio | SomeTypes.Image);
+ var st = ToXml (t1);
+ var t2 = FromXml (st);
+ Assert.AreEqual (t2.Types, t1.Types);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/Info.plist b/tests/link all/Info.plist
new file mode 100644
index 000000000000..9dafe4f5bbf2
--- /dev/null
+++ b/tests/link all/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDisplayName
+ LinkAll
+ CFBundleIdentifier
+ com.xamarin.linkall
+ MinimumOSVersion
+ 5.1.1
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ CFBundleName
+ LinkAll
+
+
diff --git a/tests/link all/InterfacesTest.cs b/tests/link all/InterfacesTest.cs
new file mode 100644
index 000000000000..cb62d254711b
--- /dev/null
+++ b/tests/link all/InterfacesTest.cs
@@ -0,0 +1,111 @@
+//
+// Linker interfaces-related Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Interfaces {
+
+ interface I {
+ void Foo ();
+ void Bar ();
+ }
+
+ class A : I {
+ public void Foo () {}
+ public void Bar () {}
+ }
+
+ class B : I {
+ public void Foo () {}
+ public void Bar () {}
+ }
+
+ class UTF8Marshaler : ICustomMarshaler {
+
+ public object MarshalNativeToManaged (IntPtr pNativeData)
+ {
+ return null;
+ }
+
+ public IntPtr MarshalManagedToNative (object managedObject)
+ {
+ return IntPtr.Zero;
+ }
+
+ public int GetNativeDataSize ()
+ {
+ return 0;
+ }
+
+ public void CleanUpManagedData (object managedObject)
+ {
+ }
+
+ public void CleanUpNativeData (IntPtr pNativeData)
+ {
+ }
+ }
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class InterfaceTest {
+
+ static void F (I i)
+ {
+ i.Bar ();
+ }
+
+ [Test]
+ public void Bug10866 ()
+ {
+ var a = new A ();
+ a.Foo ();
+ a.Bar ();
+ F (new A ());
+
+ // Foo and Bar methods are both used on A and must be present
+ Assert.NotNull (typeof(A).GetMethod ("Foo", BindingFlags.Instance | BindingFlags.Public), "A::Foo");
+ Assert.NotNull (typeof(A).GetMethod ("Bar", BindingFlags.Instance | BindingFlags.Public), "A::Bar");
+
+ // I::Foo is never used and can be removed
+ Assert.Null (typeof(I).GetMethod ("Foo", BindingFlags.Instance | BindingFlags.Public), "I::Foo");
+ // I::Bar is used in F so everyone implementing I needs Bar
+ Assert.NotNull (typeof(I).GetMethod ("Bar", BindingFlags.Instance | BindingFlags.Public), "I::Bar");
+
+ // Foo and Bar are never used on B - so Foo can be removed
+ Assert.Null (typeof(B).GetMethod ("Foo", BindingFlags.Instance | BindingFlags.Public), "B::Foo");
+ // but Bar cannot since B implements I
+ Assert.NotNull (typeof(B).GetMethod ("Bar", BindingFlags.Instance | BindingFlags.Public), "B::Bar");
+ }
+
+ [DllImport ("/usr/lib/system/libsystem_dnssd.dylib")]
+ public static extern int DNSServiceGetProperty (
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (UTF8Marshaler))] string name,
+ IntPtr result, ref uint size);
+
+ uint size;
+
+ [Test]
+ public void Bug16485 ()
+ {
+ if (size == 1)
+ DNSServiceGetProperty ("Xamarin", IntPtr.Zero, ref size);
+ // we don't want to call the function - we only want the AOT compiler to build the CustomMarshaler
+ Assert.That (size, Is.EqualTo (0), "size");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/InternalsTest.cs b/tests/link all/InternalsTest.cs
new file mode 100644
index 000000000000..daad43baf3ec
--- /dev/null
+++ b/tests/link all/InternalsTest.cs
@@ -0,0 +1,93 @@
+//
+// Link All Unit Tests for __Internal native functions
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+using MonoTouch;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.InernalCalls {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class InternalsTest {
+
+ [DllImport ("__Internal")]
+ extern static string xamarin_get_locale_country_code ();
+
+ [Test]
+ public void RegionInfo_CountryCode ()
+ {
+ Assert.IsNotNull (xamarin_get_locale_country_code (), "xamarin_get_locale_country_code");
+ }
+
+ [DllImport ("__Internal", CharSet=CharSet.Unicode)]
+ extern static void xamarin_log (string s);
+
+ [Test]
+ public void Console_Log ()
+ {
+ xamarin_log ("ascii");
+ xamarin_log ("ЉЩщӃ");
+ }
+
+#if !XAMCORE_2_0
+ [Test]
+ public void MessagingApi ()
+ {
+ Messaging.monotouch_IntPtr_objc_msgSend_IntPtr (IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ }
+#endif
+
+ [DllImport ("__Internal")]
+ extern static IntPtr xamarin_timezone_get_names (ref int count);
+
+ [Test]
+ public void TimeZone_Names ()
+ {
+ int count = 0;
+ IntPtr array = xamarin_timezone_get_names (ref count);
+ Assert.That (count, Is.GreaterThan (400), "count");
+ for (int i = 0, offset = 0; i < count; i++, offset += IntPtr.Size) {
+ IntPtr p = Marshal.ReadIntPtr (array, offset);
+ string s = Marshal.PtrToStringAnsi (p);
+ Assert.NotNull (s, i.ToString ());
+ Marshal.FreeHGlobal (p);
+ }
+ Marshal.FreeHGlobal (array);
+ }
+
+ [DllImport ("__Internal")]
+ extern static IntPtr xamarin_timezone_get_data (string name, ref int size);
+
+ [Test]
+ public void TimeZone_Data ()
+ {
+ int size = 0;
+ IntPtr data = xamarin_timezone_get_data (null, ref size);
+ Assert.That (data, Is.Not.EqualTo (IntPtr.Zero), "default");
+ Assert.That (size, Is.GreaterThan (0), "default size");
+ Marshal.FreeHGlobal (data);
+
+ data = xamarin_timezone_get_data ("America/Montreal", ref size);
+ Assert.That (data, Is.Not.EqualTo (IntPtr.Zero), "Montreal");
+ Assert.That (size, Is.GreaterThan (0), "Montreal size");
+ Marshal.FreeHGlobal (data);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/LinkAllTest.cs b/tests/link all/LinkAllTest.cs
new file mode 100644
index 000000000000..4e74e8ee8bc3
--- /dev/null
+++ b/tests/link all/LinkAllTest.cs
@@ -0,0 +1,539 @@
+//
+// Link All [Regression] Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012-2016 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+
+using MonoTouch;
+#if XAMCORE_2_0
+using CoreGraphics;
+using Foundation;
+using ObjCRuntime;
+#if !__WATCHOS__
+using StoreKit;
+#endif
+using UIKit;
+#else
+using MonoTouch.CoreGraphics;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+using MonoTouch.StoreKit;
+using MonoTouch.UIKit;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll {
+
+ // we DO NOT want the code to be "fully" available
+ public partial class NotPreserved {
+
+ public byte One {
+ get; set;
+ }
+
+ [DefaultValue (2)]
+ public int Two {
+ get; set;
+ }
+ }
+
+ // nothing directly uses Parent
+ public class Parent {
+ // but the nested type is a subclass of NSObject and gets preserved (as it's not part of monotouch.dll)
+ public class Derived : NSObject {
+ [Export ("foo")]
+ public void Foo () {}
+ }
+
+ public void UnusedMethod () {}
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class LinkAllRegressionTest {
+#if __IOS__
+#if XAMCORE_2_0
+ public const string NamespacePrefix = "";
+ public const string AssemblyName = "Xamarin.iOS";
+#else
+ public const string NamespacePrefix = "MonoTouch.";
+ public const string AssemblyName = "monotouch";
+#endif
+#elif __TVOS__
+ public const string NamespacePrefix = "";
+ public const string AssemblyName = "Xamarin.TVOS";
+#elif __WATCHOS__
+ public const string NamespacePrefix = "";
+ public const string AssemblyName = "Xamarin.WatchOS";
+#else
+ #error Unknown platform
+#endif
+
+ class TypeAttribute : Attribute {
+ public TypeAttribute (Type type) {}
+ }
+
+ [Type (null)]
+ public void NullTypeInAttribute ()
+ {
+ // there's no need to execute this test.
+ // desk #68380.
+ }
+
+ [Test]
+ public void GetterOnly ()
+ {
+ // that ensure the getter is not linked away,
+ // which means the property will be available for MEF_3862
+ NotPreserved np = new NotPreserved ();
+ Assert.That (np.Two, Is.EqualTo (0), "Two==0");
+ PropertyInfo pi = typeof (NotPreserved).GetProperty ("Two");
+ // check the *unused* setter absence from the application
+ Assert.NotNull (pi.GetGetMethod (), "getter");
+ Assert.Null (pi.GetSetMethod (), "setter");
+ }
+
+ [Test]
+ public void SetterOnly ()
+ {
+ // that ensure the setter is not linked away,
+ NotPreserved np = new NotPreserved ();
+ np.One = 1;
+ PropertyInfo pi = typeof (NotPreserved).GetProperty ("One");
+ // check the *unused* setter absence from the application
+ Assert.Null (pi.GetGetMethod (), "getter");
+ Assert.NotNull (pi.GetSetMethod (), "setter");
+ }
+
+ [Test]
+ public void MEF_3862 ()
+ {
+ // note: avoiding using "typeof(DefaultValueAttribute)" in the code
+ // so the linker does not keep it just because of it
+ PropertyInfo pi = typeof (NotPreserved).GetProperty ("Two");
+ object [] attrs = pi.GetCustomAttributes (false);
+ bool default_value = false;
+ foreach (var ca in attrs) {
+ if (ca.GetType ().Name == "DefaultValueAttribute") {
+ default_value = true;
+ break;
+ }
+ }
+ Assert.True (default_value, "DefaultValue");
+ }
+
+ class TestPolicy : ICertificatePolicy {
+
+ const int RecoverableTrustFailure = 5; // SecTrustResult
+
+ public TestPolicy ()
+ {
+ CheckCount = 0;
+ }
+
+ public int CheckCount { get; private set; }
+
+ public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
+ {
+ Assert.That (certificateProblem, Is.EqualTo (0), "certificateProblem");
+ CheckCount++;
+ return true;
+ }
+ }
+
+ static TestPolicy test_policy = new TestPolicy ();
+
+ [Test]
+ public void TrustUsingOldPolicy ()
+ {
+ // Three similar tests exists in dontlink, linkall and linksdk to test 3 different cases
+ // untrusted, custom ICertificatePolicy and ServerCertificateValidationCallback without
+ // having caching issues (in S.Net or the SSL handshake cache)
+ ICertificatePolicy old = ServicePointManager.CertificatePolicy;
+ try {
+ ServicePointManager.CertificatePolicy = test_policy;
+ WebClient wc = new WebClient ();
+ Assert.IsNotNull (wc.DownloadString ("https://wrench.internalx.com/Wrench/Login.aspx"));
+ // caching means it will be called at least for the first run, but it might not
+ // be called again in subsequent requests (unless it expires)
+ Assert.That (test_policy.CheckCount, Is.GreaterThan (0), "policy checked");
+ }
+ finally {
+ ServicePointManager.CertificatePolicy = old;
+ }
+ }
+
+ [Test]
+ public void DetectPlatform ()
+ {
+#if !__WATCHOS__
+ // for (future) nunit[lite] platform detection - if this test fails then platform detection won't work
+ Assert.NotNull (Type.GetType (NamespacePrefix + "UIKit.UIApplicationDelegate, " + AssemblyName), "UIApplicationDelegate");
+#endif
+ // and you can trust the old trick with the linker
+ Assert.NotNull (Type.GetType ("Mono.Runtime"), "Mono.Runtime");
+ }
+
+ [Test]
+#if !XAMCORE_2_0
+ // internal (to be removed) in unified
+ [Since (9,9)]
+#endif
+#if !XAMCORE_3_0
+ [Availability ()]
+ [iOS (9,9)]
+ [Mac (10, 99)]
+#endif
+ [Introduced (PlatformName.None)]
+ [Deprecated (PlatformName.None)]
+ [Obsoleted (PlatformName.None)]
+ [Unavailable (PlatformName.None)]
+ [ThreadSafe]
+ public void RemovedAttributes ()
+ {
+ const string prefix = NamespacePrefix;
+ const string suffix = ", " + AssemblyName;
+
+ // since we're linking the attributes will NOT be available - even if they are used
+#if !XAMCORE_3_0
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.AvailabilityAttribute, " + suffix), "AvailabilityAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.iOSAttribute, " + suffix), "AvailabilityAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.AvailabilityAttribute, " + suffix), "AvailabilityAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.SinceAttribute, " + suffix), "SinceAttribute");
+#endif
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.IntroducedAttribute, " + suffix), "IntroducedAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.DeprecatedAttribute, " + suffix), "DeprecatedAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.ObsoletedAttribute, " + suffix), "ObsoletedAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.UnavailableAttribute, " + suffix), "UnavailableAttribute");
+ Assert.Null (Type.GetType (prefix + "ObjCRuntime.ThreadSafeAttribute, " + suffix), "ThreadSafeAttribute");
+ }
+
+ [Test]
+ public void Assembly_Load ()
+ {
+ Assembly mscorlib = Assembly.Load ("mscorlib.dll");
+ Assert.NotNull (mscorlib, "mscorlib");
+
+ Assembly system = Assembly.Load ("System.dll");
+ Assert.NotNull (system, "System");
+ }
+
+ [Test]
+ public void Assembly_LoadFile ()
+ {
+ string filename = Path.GetFileName (GetType ().Assembly.Location);
+ try {
+ Assert.NotNull (Assembly.LoadFile (filename), "1");
+ }
+ catch (FileNotFoundException) {
+ // 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too)
+ filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename);
+ Assert.NotNull (Assembly.LoadFile (filename), "2");
+ }
+ }
+
+ [Test]
+ public void Assembly_LoadFrom ()
+ {
+ string filename = Path.GetFileName (GetType ().Assembly.Location);
+ try {
+ Assert.NotNull (Assembly.LoadFrom (filename), "1");
+ }
+ catch (FileNotFoundException) {
+ // 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too)
+ filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename);
+ Assert.NotNull (Assembly.LoadFrom (filename), "2");
+ }
+ }
+
+ [Test]
+ public void Assembly_ReflectionOnlyLoadFrom ()
+ {
+ string filename = Path.GetFileName (GetType ().Assembly.Location);
+ try {
+ Assert.NotNull (Assembly.ReflectionOnlyLoadFrom (filename), "1");
+ }
+ catch (FileNotFoundException) {
+ // 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too)
+ filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename);
+ Assert.NotNull (Assembly.ReflectionOnlyLoadFrom (filename), "2");
+ }
+ }
+
+ [Test]
+ public void SystemDataSqlClient ()
+ {
+ // notes:
+ // * this test is mean to fail when building the application using a Community or Indie licenses
+ // * linksdk.app references System.Data (assembly) but not types in SqlClient namespace
+ using (var sc = new System.Data.SqlClient.SqlConnection ()) {
+ Assert.NotNull (sc);
+ }
+ }
+
+#if !__TVOS__ && !__WATCHOS__
+ [Test]
+ public void Pasteboard_ImagesTest ()
+ {
+ string file = Path.Combine (NSBundle.MainBundle.ResourcePath, "basn3p08.png");
+ using (var dp = new CGDataProvider (file)) {
+ using (var cgimg = CGImage.FromPNG (dp, null, false, CGColorRenderingIntent.Default)) {
+ using (var img = new UIImage (cgimg)) {
+ UIPasteboard.General.Images = new UIImage[] { img };
+ Assert.AreEqual (1, UIPasteboard.General.Images.Length, "a - length");
+
+ UIPasteboard.General.Images = new UIImage[] { img, img };
+ Assert.AreEqual (2, UIPasteboard.General.Images.Length, "b - length");
+ Assert.IsNotNull (UIPasteboard.General.Images [0], "b - nonnull[0]");
+ Assert.IsNotNull (UIPasteboard.General.Images [1], "b - nonnull[0]");
+ }
+ }
+ }
+ }
+#endif // !__TVOS__
+
+ [Test]
+ public void UltimateBindings ()
+ {
+ Assert.IsNotNull (Bindings.Test.UltimateMachine.SharedInstance, "SharedInstance");
+ }
+
+ #region bug 14456
+
+ [TypeConverter (typeof (TestEnumTypeConverter))]
+ public enum TestEnum {
+ One,Two
+ }
+
+ [Preserve (AllMembers = true)]
+ public class TestEnumTypeConverter : System.ComponentModel.TypeConverter {
+
+ public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ return "hello";
+ }
+ }
+
+ [Test]
+ public void Bug14456 ()
+ {
+ var tc = TypeDescriptor.GetConverter (typeof (TestEnum));
+ // not using Is.TypeOf since it would give additional clue to the linker
+ Assert.That (tc.GetType ().Name, Is.EqualTo ("TestEnumTypeConverter"), "TestEnumTypeConverter");
+ // notes:
+ // * without [Preserve (AllMembers = true)] -> MissingMethodException : Default constructor
+ // * without [TypeConverter (typeof (TestEnumTypeConverter))] -> EnumConverter
+ }
+
+ #endregion
+
+ [Test]
+ public void SingleEpsilon_Compare ()
+ {
+ if (Runtime.Arch == Arch.DEVICE)
+ Assert.Ignore ("Known to fail on devices, see bug #15802");
+ // works on some ARM CPU (e.g. iPhone5S) but not others (iPad4 or iPodTouch5)
+ Assert.That (Single.Epsilon, Is.Not.EqualTo (0f), "Epsilon");
+ Assert.That (-Single.Epsilon, Is.Not.EqualTo (0f), "-Epsilon");
+ }
+
+ [Test]
+ public void SingleEpsilon_ToString ()
+ {
+ if (Runtime.Arch == Arch.DEVICE)
+ Assert.Ignore ("Known to fail on devices, see bug #15802");
+ var ci = CultureInfo.InvariantCulture;
+ Assert.That (Single.Epsilon.ToString (ci), Is.EqualTo ("1.401298E-45"), "Epsilon.ToString()");
+ Assert.That ((-Single.Epsilon).ToString (ci), Is.EqualTo ("-1.401298E-45"), "-Epsilon.ToString()");
+ }
+
+ [Test]
+ public void DoubleEpsilon_Compare ()
+ {
+ if (Runtime.Arch == Arch.DEVICE)
+ Assert.Ignore ("Known to fail on devices, see bug #15802");
+ // works on some ARM CPU (e.g. iPhone5S) but not others (iPad4 or iPodTouch5)
+ Assert.That (Double.Epsilon, Is.Not.EqualTo (0f), "Epsilon");
+ Assert.That (-Double.Epsilon, Is.Not.EqualTo (0f), "-Epsilon");
+ }
+
+ [Test]
+ public void DoubleEpsilon_ToString ()
+ {
+ if (Runtime.Arch == Arch.DEVICE)
+ Assert.Ignore ("Known to fail on devices, see bug #15802");
+ var ci = CultureInfo.InvariantCulture;
+ // note: unlike Single this works on both my iPhone5S and iPodTouch5
+ Assert.That (Double.Epsilon.ToString (ci), Is.EqualTo ("4.94065645841247E-324"), "Epsilon.ToString()");
+ Assert.That ((-Double.Epsilon).ToString (ci), Is.EqualTo ("-4.94065645841247E-324"), "-Epsilon.ToString()");
+ }
+
+ [Test]
+ public void AssemblyReferences_16213 ()
+ {
+ foreach (var assembly in typeof (System.Data.AcceptRejectRule).Assembly.GetReferencedAssemblies ()) {
+ // Unlike the original bug report the unit tests uses Mono.Data.Tds so it will be part of the .app
+ // so we check for System.Transactions which is not used (but referenced by the original System.Data)
+ if (assembly.Name == "System.Transactions")
+ Assert.Fail ("System.Transactions reference should have removed by the linker");
+ }
+ }
+
+#if !__WATCHOS__
+ [Test]
+ public void OpenTk10_Preserved ()
+ {
+ // that will bring OpenTK-1.0 into the .app
+ OpenTK.WindowState state = OpenTK.WindowState.Normal;
+
+ var gl = Type.GetType ("OpenTK.Graphics.ES11.GL, OpenTK-1.0", false);
+ Assert.NotNull (gl, "ES11/GL");
+ var core = Type.GetType ("OpenTK.Graphics.ES11.GL/Core, OpenTK-1.0", false);
+ Assert.NotNull (core, "ES11/Core");
+
+ gl = Type.GetType ("OpenTK.Graphics.ES20.GL, OpenTK-1.0", false);
+ Assert.NotNull (gl, "ES20/GL");
+ core = Type.GetType ("OpenTK.Graphics.ES20.GL/Core, OpenTK-1.0", false);
+ Assert.NotNull (core, "ES20/Core");
+ }
+#endif // !__WATCHOS__
+
+ [Test]
+ public void NestedNSObject ()
+ {
+ // Parent type is not used - but it's not linked out
+ var p = Type.GetType ("LinkAll.Parent");
+ Assert.NotNull (p, "Parent");
+ // because a nested type is a subclass of NSObject (and not part of monotouch.dll)
+ var n = p.GetNestedType ("Derived");
+ Assert.NotNull (n, "Derived");
+ // however other stuff in Parent, like unused methods, will be removed
+ Assert.Null (p.GetMethod ("UnusedMethod"), "unused method");
+ // while exported stuff will be present
+ Assert.NotNull (n.GetMethod ("Foo"), "unused Export method");
+ }
+
+ [Test]
+ public void Bug20363 ()
+ {
+ // testing compile time error
+ CancelEventArgs cea = new CancelEventArgs ();
+ Assert.NotNull (cea, "CancelEventArgs");
+ }
+
+ string GetField (object o, string s)
+ {
+ var f = o.GetType ().GetField (s, BindingFlags.Instance | BindingFlags.NonPublic);
+ if (f == null)
+ return s;
+ //Console.WriteLine (f.GetValue (o));
+ return null;
+ }
+
+ string FromPattern (string pattern, object o)
+ {
+ var s = GetField (o, "");
+ if (s != null)
+ return s;
+ s = GetField (o, "");
+ if (s != null)
+ return s;
+ return GetField (o, "");
+ }
+
+ [Test]
+ public void AnonymousType ()
+ {
+ var result = FromPattern ("/{action}/{id}.{contentType}", new {
+ action = "foo",
+ id = 1234,
+ contentType = "xml"
+ });
+ Assert.Null (result, result);
+ }
+
+#if !__WATCHOS__
+ [Test]
+ public void Events ()
+ {
+ using (var pr = new SKProductsRequest ()) {
+ Assert.Null (pr.WeakDelegate, "none");
+ // event on SKProductsRequest itself
+ pr.ReceivedResponse += (object sender, SKProductsRequestResponseEventArgs e) => {};
+
+ var t = pr.WeakDelegate.GetType ();
+ Assert.That (t.Name, Is.EqualTo ("_SKProductsRequestDelegate"), "delegate");
+
+ var fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance);
+ Assert.NotNull (fi, "receivedResponse");
+ var value = fi.GetValue (pr.WeakDelegate);
+ Assert.NotNull (value, "value");
+
+#if XAMCORE_2_0
+ // and on the SKRequest defined one
+ pr.RequestFailed += (object sender, SKRequestErrorEventArgs e) => {};
+ // and the existing (initial field) is still set
+ fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance);
+ Assert.NotNull (fi, "receivedResponse/SKRequest");
+#else
+ // In Classic SKRequest also defines a RequestFailed event, so make sure we get the SKRequest one
+ // that's because event are re-defined (new) in classic
+ ((SKRequest) pr).RequestFailed += (object sender, SKRequestErrorEventArgs e) => {};
+
+ t = pr.WeakDelegate.GetType ();
+ Assert.That (t.Name, Is.EqualTo ("_SKRequestDelegate"), "delegate-2");
+
+ fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance);
+ Assert.Null (fi, "receivedResponse/SKRequest");
+#endif
+ }
+ }
+#endif // !__WATCHOS__
+
+ [Test]
+ public void Aot_27116 ()
+ {
+ var nix = (from nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces ()
+ where nic.Id.StartsWith ("en") || nic.Id.StartsWith ("pdp_ip") select nic);
+ Assert.NotNull (nix);
+ }
+
+ [Test]
+ public void TlsProvider_Legacy ()
+ {
+ var provider = Mono.Security.Interface.MonoTlsProviderFactory.GetProvider ();
+ Assert.NotNull (provider, "provider");
+ Assert.That (provider.ID, Is.EqualTo (new Guid ("97d31751-d0b3-4707-99f7-a6456b972a19")), "correct provider");
+ }
+
+ [Test]
+ public void OldTlsProvider_Selected ()
+ {
+ // make test work for classic (monotouch) and unified (iOS, tvOS and watchOS)
+ var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.OldTlsProvider");
+ Assert.NotNull (Type.GetType (fqn), "Should be included");
+ }
+
+ [Test]
+ public void AppleTls_OptOut ()
+ {
+ // make test work for classic (monotouch) and unified (iOS, tvOS and watchOS)
+ var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.AppleTlsProvider");
+ Assert.Null (Type.GetType (fqn), "Should not be included");
+ }
+ }
+}
diff --git a/tests/link all/LinqExpressionTest.cs b/tests/link all/LinqExpressionTest.cs
new file mode 100644
index 000000000000..f0862601993a
--- /dev/null
+++ b/tests/link all/LinqExpressionTest.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Linq.Expressions;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Linq {
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class LinqExpressionTest {
+
+ // Normally this test would have been included in linksdk.app - but there's already
+ // some code that (indirectly) includes the code we want to test (so it can't fail)
+
+ delegate object Bug14863Delegate ();
+
+ [Test]
+ public void Expression_T_Ctor ()
+ {
+ var ctor = typeof (LinqExpressionTest).GetConstructor (Type.EmptyTypes);
+ var expr = Expression.New (ctor, new Expression [0]);
+ Assert.NotNull (Expression.Lambda (typeof(Bug14863Delegate), expr, null), "Lambda");
+ // note: reflection is used to create an instance of Expression using an internal ctor
+ // it can be indirectly "preserved" by other code (in Expression) but it can fail in other cases
+ // ref: https://bugzilla.xamarin.com/show_bug.cgi?id=14863
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/MEFTests.cs b/tests/link all/MEFTests.cs
new file mode 100644
index 000000000000..190b093eaca7
--- /dev/null
+++ b/tests/link all/MEFTests.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.ComponentModel.Composition.Hosting;
+using System.Linq;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Mef {
+
+ // From Desk Case 70807
+ public interface IStorageType
+ {
+ }
+
+ [System.ComponentModel.Composition.Export(typeof (IStorageType))]
+ [Preserve (AllMembers = true)]
+ public class Storage : IStorageType
+ {
+ }
+
+ [Preserve (AllMembers = true)]
+ [TestFixture]
+ public class MEFTests
+ {
+ CompositionContainer _container;
+
+ [ImportMany]
+ public IEnumerable> StorageTypes { get; set; }
+
+ [Test]
+ public void MEF_Basic_Import_Test ()
+ {
+ var catalog = new AggregateCatalog ();
+ //Adds all the parts found in the same assembly as the Program class
+ catalog.Catalogs.Add (new AssemblyCatalog (typeof (Application).Assembly));
+
+ //Create the CompositionContainer with the parts in the catalog
+ _container = new CompositionContainer (catalog);
+
+ this._container.SatisfyImportsOnce (this);
+
+ Assert.IsTrue (StorageTypes.Count () > 0, "No MEF imports found?");
+ }
+
+ [Test]
+ public void ExportFactoryCreator ()
+ {
+ // the above code makes sure that ExportFactoryCreator is present
+ var efc = Type.GetType ("System.ComponentModel.Composition.ReflectionModel.ExportFactoryCreator, System.ComponentModel.Composition");
+ Assert.NotNull (efc, "ExportFactoryCreator");
+
+ // and there's nothing else that refers to them - hence bug: https://bugzilla.xamarin.com/show_bug.cgi?id=29063
+ // as it's used thru reflection in CreateStronglyTypedExportFactoryFactory
+ var t = efc.GetMethod ("CreateStronglyTypedExportFactoryOfT", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // same binding flags as MS code
+ Assert.NotNull (t, "CreateStronglyTypedExportFactoryOfT");
+ var tm = efc.GetMethod ("CreateStronglyTypedExportFactoryOfTM", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // same binding flags as MS code
+ Assert.NotNull (tm, "CreateStronglyTypedExportFactoryOfTM");
+ }
+
+ [Test]
+ public void ExportServices ()
+ {
+ var es = Type.GetType ("System.ComponentModel.Composition.ExportServices, System.ComponentModel.Composition");
+ Assert.NotNull (es, "ExportServices");
+ // unlike the test code for ExportFactoryCreator the method can be marked by other call site, so this test is not 100% conclusive
+
+ // used, thru reflection, from CreateStronglyTypedLazyFactory method
+ var t = es.GetMethod ("CreateStronglyTypedLazyOfT", BindingFlags.NonPublic | BindingFlags.Static); // same binding flags as MS code
+ Assert.NotNull (t, "CreateStronglyTypedLazyOfT");
+ var tm = es.GetMethod ("CreateStronglyTypedLazyOfTM", BindingFlags.NonPublic | BindingFlags.Static); // same binding flags as MS code
+ Assert.NotNull (tm, "CreateStronglyTypedLazyOfTM");
+
+ // used, thru reflection, from CreateSemiStronglyTypedLazyFactory method
+ var l = es.GetMethod ("CreateSemiStronglyTypedLazy", BindingFlags.NonPublic | BindingFlags.Static); // same binding flags as MS code
+ Assert.NotNull (l, "CreateSemiStronglyTypedLazy");
+ }
+ }
+}
diff --git a/tests/link all/Main.cs b/tests/link all/Main.cs
new file mode 100644
index 000000000000..c9b0815dd93e
--- /dev/null
+++ b/tests/link all/Main.cs
@@ -0,0 +1,23 @@
+using System;
+
+#if XAMCORE_2_0
+using UIKit;
+#else
+using MonoTouch.UIKit;
+#endif
+
+namespace LinkAll
+{
+ public class Application
+ {
+#if !__WATCHOS__
+ // This is the main entry point of the application.
+ static void Main (string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main (args, null, "AppDelegate");
+ }
+#endif // !__WATCHOS__
+ }
+}
diff --git a/tests/link all/PreserveTest.cs b/tests/link all/PreserveTest.cs
new file mode 100644
index 000000000000..f83addf0961f
--- /dev/null
+++ b/tests/link all/PreserveTest.cs
@@ -0,0 +1,168 @@
+//
+// Preserve tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2013-2016 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Reflection;
+#if XAMCORE_2_0
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+using NUnit.Framework;
+
+// this will preserve the specified type (only)
+[assembly: Preserve (typeof (LinkAll.Attributes.TypeWithoutMembers))]
+
+// this will preserve the specified type with all it's members
+[assembly: Preserve (typeof (LinkAll.Attributes.TypeWithMembers), AllMembers = true)]
+
+// as the preserved field is an attribute this means that [Obfuscation] becomes like [Preserve]
+// IOW preserving the attribute does not do much good if what it decorates gets removed
+[assembly: Preserve (typeof (ObfuscationAttribute))]
+
+namespace LinkAll.Attributes {
+
+ // type and members preserved by assembly-level attribute above
+ class TypeWithMembers {
+
+ public string Present { get; set; }
+ }
+
+ // type (only, not members) preserved by assembly-level attribute above
+ class TypeWithoutMembers {
+
+ public string Absent { get; set; }
+ }
+
+ class MemberWithCustomAttribute {
+
+ // since [Obfuscation] was manually preserved then we'll preserve everything that's decorated with the attribute
+ [Obfuscation]
+ public string Custom { get; set; }
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class PreserveTest {
+
+#if DEBUG
+ const bool Debug = true;
+#else
+ const bool Debug = false;
+#endif
+#if XAMCORE_2_0
+ const string NamespacePrefix = "";
+ string AssemblyName = typeof (NSObject).Assembly.ToString ();
+#else
+ const string NamespacePrefix = "MonoTouch.";
+ const string AssemblyName = "monotouch";
+#endif
+
+ [Test]
+ public void PreserveTypeWithMembers ()
+ {
+ var t = Type.GetType ("LinkAll.Attributes.TypeWithMembers");
+ // both type and members are preserved
+ Assert.NotNull (t, "type");
+ Assert.NotNull (t.GetProperty ("Present"), "members");
+ }
+
+ [Test]
+ public void PreserveTypeWithoutMembers ()
+ {
+ var t = Type.GetType ("LinkAll.Attributes.TypeWithoutMembers");
+ // type is preserved
+ Assert.NotNull (t, "type");
+ // but we did not ask the linker to preserve it's members
+ Assert.Null (t.GetProperty ("Absent"), "members");
+ }
+
+ [Test]
+ public void PreserveTypeWithCustomAttribute ()
+ {
+ var t = Type.GetType ("LinkAll.Attributes.MemberWithCustomAttribute");
+ // both type and members are preserved - in this case the type is preserved because it's member was
+ Assert.NotNull (t, "type");
+ // and that member was preserved because it's decorated with a preserved attribute
+ Assert.NotNull (t.GetProperty ("Custom"), "members");
+ }
+
+ [Test]
+ public void Class_LookupFullName ()
+ {
+ var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Class, " + AssemblyName);
+ Assert.NotNull (klass, "Class");
+ // only required (and preserved) for debug builds
+ var method = klass.GetMethod ("LookupFullName", BindingFlags.NonPublic | BindingFlags.Static);
+ // note: since iOS/runtime unification this is being called by ObjCRuntime.Runtime.LookupManagedTypeName
+ // and will never be removed (even on Release builds)
+ Assert.NotNull (method, "LookupFullName");
+ }
+
+ [Test]
+ public void Runtime_RegisterEntryAssembly ()
+ {
+ var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Runtime, " + AssemblyName);
+ Assert.NotNull (klass, "Runtime");
+ // RegisterEntryAssembly is only needed for the simulator (not on devices) so it's only preserved for sim builds
+ var method = klass.GetMethod ("RegisterEntryAssembly", BindingFlags.NonPublic | BindingFlags.Static, null, new [] { typeof (Assembly) }, null);
+ Assert.That (method == null, Is.EqualTo (Runtime.Arch == Arch.DEVICE), "RegisterEntryAssembly");
+ }
+
+ [Test]
+ public void MonoTouchException_Unconditional ()
+ {
+ var klass = Type.GetType (NamespacePrefix + "Foundation.MonoTouchException, " + AssemblyName);
+ Assert.NotNull (klass, "MonoTouchException");
+ }
+
+ [Test]
+ public void Class_Unconditional ()
+ {
+ var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Class, " + AssemblyName);
+ Assert.NotNull (klass, "Class");
+ // handle is unconditionally preserved
+ var field = klass.GetField ("handle", BindingFlags.NonPublic | BindingFlags.Instance);
+ Assert.NotNull (field, "handle");
+ }
+
+ [Test]
+ public void Runtime_Unconditional ()
+ {
+ var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Runtime, " + AssemblyName);
+ Assert.NotNull (klass, "Runtime");
+ // Initialize, RegisterAssembly... are unconditionally preserved
+ var method = klass.GetMethod ("Initialize", BindingFlags.NonPublic | BindingFlags.Static);
+ Assert.NotNull (method, "Initialize");
+ method = klass.GetMethod ("RegisterAssembly", BindingFlags.Public | BindingFlags.Static);
+ Assert.NotNull (method, "RegisterAssembly");
+ method = klass.GetMethod ("RegisterNSObject", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof (NSObject), typeof (IntPtr) }, null);
+ Assert.NotNull (method, "RegisterNSObject");
+ method = klass.GetMethod ("GetBlockWrapperCreator", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof (MethodInfo), typeof (int) }, null);
+ Assert.NotNull (method, "GetBlockWrapperCreator");
+ method = klass.GetMethod ("CreateBlockProxy", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof (MethodInfo), typeof (IntPtr) }, null);
+ Assert.NotNull (method, "CreateBlockProxy");
+ }
+
+ [Test]
+ public void Selector_Unconditional ()
+ {
+ var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Selector, " + AssemblyName);
+ Assert.NotNull (klass, "Selector");
+ // handle and is unconditionally preserved
+ var field = klass.GetField ("handle", BindingFlags.NonPublic | BindingFlags.Instance);
+ Assert.NotNull (field, "handle");
+ var method = klass.GetMethod ("GetHandle", BindingFlags.Public | BindingFlags.Static);
+ Assert.NotNull (method, "GetHandle");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/SealerTest.cs b/tests/link all/SealerTest.cs
new file mode 100644
index 000000000000..d6dab5737d3d
--- /dev/null
+++ b/tests/link all/SealerTest.cs
@@ -0,0 +1,71 @@
+// Copyright 2016 Xamarin Inc. All rights reserved.
+
+using System;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace Linker.Sealer {
+
+ [Preserve (AllMembers = true)]
+ public class Unsealable {
+
+ public virtual bool A () { return true; }
+ public virtual bool B () { return false; }
+ }
+
+ [Preserve (AllMembers = true)]
+ public class Sealable : Unsealable {
+ public override bool B () { return true; }
+ }
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class SealerTest {
+
+ [Test]
+ public void Sealed ()
+ {
+ // this can not be optimized into a sealed type
+ Assert.False (typeof (Unsealable).IsSealed, "Unsealed");
+#if DEBUG
+ // this is not a sealed type (in the source)
+ Assert.False (typeof (Sealable).IsSealed, "Sealed");
+#else
+ // but it can be optimized / sealed as nothing else is (or can) subclass it
+ Assert.True (typeof (Sealable).IsSealed, "Sealed");
+#endif
+ }
+
+ [Test]
+ public void Final ()
+ {
+ var t = typeof (Sealable);
+#if DEBUG
+ // this is not a sealed method (in the source)
+ Assert.False (t.GetMethod ("B").IsFinal, "Not Final");
+#else
+ // but it can be optimized / sealed as nothing else is (or can) overrides it
+ Assert.True (t.GetMethod ("B").IsFinal, "Final");
+#endif
+ }
+
+ [Test]
+ public void Virtual ()
+ {
+ var t = typeof (Sealable);
+#if DEBUG
+ // both methods are virtual (iin the source)
+ Assert.True (t.GetMethod ("A").IsVirtual, "A");
+ Assert.True (t.GetMethod ("B").IsVirtual, "B");
+#else
+ // but A can be de-virtualized as it overrides nothing and is not overridden
+ Assert.False (t.GetMethod ("A").IsVirtual, "A");
+ Assert.True (t.GetMethod ("B").IsVirtual, "B");
+#endif
+ }
+ }
+}
diff --git a/tests/link all/SerializationTest.cs b/tests/link all/SerializationTest.cs
new file mode 100644
index 000000000000..5f2315367103
--- /dev/null
+++ b/tests/link all/SerializationTest.cs
@@ -0,0 +1,96 @@
+//
+// Link All [Regression] Tests for Serialization
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2016 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Runtime.Serialization;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Serialization {
+
+ [Serializable]
+ public class Unused {
+
+ [OnDeserializing]
+ void Deserializing ()
+ {
+ }
+
+ [OnDeserialized]
+ void Deserialized ()
+ {
+ }
+
+ [OnSerializing]
+ void Serializing ()
+ {
+ }
+
+ [OnSerialized]
+ void Serialized ()
+ {
+ }
+ }
+
+ [Serializable]
+ public class Used {
+
+ [OnDeserializing]
+ void Deserializing ()
+ {
+ }
+
+ [OnDeserialized]
+ void Deserialized ()
+ {
+ }
+
+ [OnSerializing]
+ void Serializing ()
+ {
+ }
+
+ [OnSerialized]
+ void Serialized ()
+ {
+ }
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class SerializationAttributeTests {
+
+ [Test]
+ public void UnusedType ()
+ {
+ // the serialization attributes only keeps the method(s) if the type was used
+ var t = Type.GetType ("LinkAll.Serialization.Unused");
+ // since it's not used in the app then it's removed by the linker
+ Assert.Null (t, "type");
+ }
+
+ [Test]
+ public void UsedType ()
+ {
+ // the serialization attributes only keeps the method(s) if the type was used
+ var t = Type.GetType ("LinkAll.Serialization.Used");
+ // since it's used here...
+ Assert.NotNull (new Used (), "reference");
+ // it's not removed by the linker
+ Assert.NotNull (t, "type");
+ // and since it's not the 4 decorated methods are also kept (even if uncalled)
+ Assert.That (t.GetMethods ().Length, Is.EqualTo (4), "4");
+ }
+ }
+}
diff --git a/tests/link all/StructLayoutTest.cs b/tests/link all/StructLayoutTest.cs
new file mode 100644
index 000000000000..2ef9634b7149
--- /dev/null
+++ b/tests/link all/StructLayoutTest.cs
@@ -0,0 +1,113 @@
+//
+// Link All [Regression] Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.Runtime.InteropServices;
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+using NUnit.Framework;
+
+namespace LinkAll.Layout {
+
+ struct DefaultStruct {
+ public int never_used;
+ public int used;
+ }
+
+ [StructLayout (LayoutKind.Auto)]
+ struct AutoStruct {
+ public int never_used;
+ public int used;
+ }
+
+ [StructLayout (LayoutKind.Sequential)]
+ struct SequentialStruct {
+ public int never_used;
+ public int used;
+ }
+
+ [StructLayout (LayoutKind.Explicit)]
+ struct ExplicitStruct {
+ [FieldOffset (0)]
+ public int never_used;
+ [FieldOffset (4)]
+ public int used;
+ [FieldOffset (8)]
+ public int never_ever_used;
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class StructLayoutTest {
+
+ [Test]
+ public void DefaultLayoutStruct () // sequential
+ {
+ DefaultStruct c = new DefaultStruct ();
+ c.used = 1;
+ Assert.That (Marshal.SizeOf (c), Is.EqualTo (8), "2 fields");
+ var t = typeof (DefaultStruct);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (2), "Length");
+
+ Assert.False (t.IsAutoLayout, "IsAutoLayout");
+ Assert.False (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.True (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+
+ [Test]
+ public void AutoLayoutStruct ()
+ {
+ AutoStruct c = new AutoStruct ();
+ c.used = 1;
+ // can't ask SizeOf on Auto
+ var t = typeof (AutoStruct);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (2), "Length");
+
+ Assert.True (t.IsAutoLayout, "IsAutoLayout");
+ Assert.False (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.False (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+
+ [Test]
+ public void LayoutSequential ()
+ {
+ SequentialStruct c = new SequentialStruct ();
+ c.used = 1;
+ Assert.That (Marshal.SizeOf (c), Is.EqualTo (8), "2 fields");
+ var t = typeof (SequentialStruct);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (2), "Length");
+
+ Assert.False (t.IsAutoLayout, "IsAutoLayout");
+ Assert.False (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.True (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+
+ [Test]
+ public void ExplicitLayout ()
+ {
+ ExplicitStruct c = new ExplicitStruct ();
+ c.used = 1;
+ Assert.That (Marshal.SizeOf (c), Is.GreaterThanOrEqualTo (12), "3 fields");
+ var t = typeof (ExplicitStruct);
+ var fields = t.GetFields ();
+ Assert.That (fields.Length, Is.EqualTo (3), "Length");
+
+ Assert.False (t.IsAutoLayout, "IsAutoLayout");
+ Assert.True (t.IsExplicitLayout, "IsExplicitLayout");
+ Assert.False (t.IsLayoutSequential, "IsLayoutSequential");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/link all/XmlSerializationTest.cs b/tests/link all/XmlSerializationTest.cs
new file mode 100644
index 000000000000..34da3861a1d4
--- /dev/null
+++ b/tests/link all/XmlSerializationTest.cs
@@ -0,0 +1,79 @@
+//
+// Link All Xml Serialization Tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright 2012 Xamarin Inc. All rights reserved.
+//
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+
+#if XAMCORE_2_0
+using Foundation;
+#else
+using MonoTouch.Foundation;
+#endif
+
+using NUnit.Framework;
+
+namespace LinkAll.Serialization.Xml {
+
+ [Serializable]
+ [XmlRoot ("rsp", IsNullable = false)]
+ public class XmlResult {
+ [XmlAttribute ("stat")]
+ public int StatusCode { get; set; }
+
+ [XmlElement ("photos")]
+ [XmlElement ("photosets")]
+ public T Result { get; set; }
+ }
+
+ [Serializable]
+ [XmlRoot ("rsp")]
+ public class XmlField {
+ [XmlElement ("photos")]
+ [XmlElement ("photosets")]
+ public T Result;
+ }
+
+ [TestFixture]
+ // we want the tests to be available because we use the linker
+ [Preserve (AllMembers = true)]
+ public class XmlSerializationTest {
+
+ [Test]
+ public void GenericProperty_Bug5543 ()
+ {
+ XmlResult r = new XmlResult ();
+ r.Result = "5543";
+ r.StatusCode = 10;
+
+ var serializer = new XmlSerializer (typeof (XmlResult));
+ using (var ms = new MemoryStream ()) {
+ serializer.Serialize (ms, r);
+ r.Result = String.Empty;
+ r.StatusCode = -1;
+
+ ms.Position = 0;
+ XmlResult back = (XmlResult) serializer.Deserialize (ms);
+
+ Assert.That (back.Result, Is.EqualTo ("5543"), "Result");
+ Assert.That (back.StatusCode, Is.EqualTo (10), "StatusCode");
+ }
+ }
+
+ [Test]
+ public void GenericField ()
+ {
+ XmlField f = new XmlField ();
+ f.Result = "5543";
+ // not valid for serialization but the linker should not have issue with that
+ }
+ }
+}
+
diff --git a/tests/link all/basn3p08.png b/tests/link all/basn3p08.png
new file mode 100644
index 000000000000..0ddad07e5f5d
Binary files /dev/null and b/tests/link all/basn3p08.png differ
diff --git a/tests/link all/link all.csproj b/tests/link all/link all.csproj
new file mode 100644
index 000000000000..cc2f01d2e519
--- /dev/null
+++ b/tests/link all/link all.csproj
@@ -0,0 +1,126 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 8.0.30703
+ 2.0
+ {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}
+ {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Exe
+ linkall
+ link all
+ MonoTouch
+
+
+ True
+ full
+ False
+ bin\iPhoneSimulator\Debug
+ DEBUG;LINKALL;
+ prompt
+ 4
+ False
+ True
+ Full
+ mideast,other
+ --registrar=static --tls-provider=legacy
+ i386
+
+
+ none
+ False
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ False
+ Full
+ mideast,other
+ i386
+ LINKALL;
+ --tls-provider=legacy
+
+
+ True
+ full
+ False
+ bin\iPhone\Debug
+ DEBUG;LINKALL;
+ prompt
+ 4
+ False
+ iPhone Developer
+ True
+ Full
+ mideast,other
+ ARMv7
+ --tls-provider=legacy
+
+
+ none
+ False
+ bin\iPhone\Release
+ prompt
+ 4
+ False
+ iPhone Developer
+ Full
+ mideast,other
+ True
+ ARMv7
+ -v -v -v -v --tls-provider=legacy
+ LINKALL;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OptimizeGeneratedCodeTest.cs
+
+
+
+
+
+
+
+
+ ReflectionTest.cs
+
+
+
+
+
+
+
+
+ {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}
+ BundledResources
+
+
+ {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}
+ bindings-test
+
+
+
+
\ No newline at end of file
diff --git a/tests/link sdk/AotBugs.cs b/tests/link sdk/AotBugs.cs
new file mode 100644
index 000000000000..b6324bef4518
--- /dev/null
+++ b/tests/link sdk/AotBugs.cs
@@ -0,0 +1,620 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+#if !__WATCHOS__
+using System.Drawing;
+#endif
+using System.Linq;
+using System.Threading.Tasks;
+using System.Runtime.CompilerServices;
+#if XAMCORE_2_0
+using CoreGraphics;
+using Foundation;
+using ObjCRuntime;
+#else
+using MonoTouch.CoreGraphics;
+using MonoTouch.Foundation;
+using MonoTouch.ObjCRuntime;
+#endif
+
+#if XAMCORE_2_0
+using RectangleF=CoreGraphics.CGRect;
+using SizeF=CoreGraphics.CGSize;
+using PointF=CoreGraphics.CGPoint;
+#else
+using nfloat=global::System.Single;
+using nint=global::System.Int32;
+using nuint=global::System.UInt32;
+#endif
+
+using NUnit.Framework;
+
+namespace LinkSdk.Aot {
+
+ static class AotExtension {
+
+ // https://bugzilla.xamarin.com/show_bug.cgi?id=3285
+ public static IEnumerable GetInterfaces(this Type type, Type interfaceType)
+ {
+ Type[] interfaces = type.GetInterfaces();
+ foreach (Type t in interfaces) {
+ Type typeToCheck = t;
+ if (t.IsGenericType)
+ typeToCheck = t.GetGenericTypeDefinition();
+ if (typeToCheck == interfaceType)
+ yield return t;
+ }
+ yield break;
+ }
+ }
+
+ interface IAotTest {
+ }
+
+ [TestFixture]
+ // already done in Bug2096Test.cs -> [Preserve (AllMembers = true)]
+ public partial class AotBugsTest : IAotTest {
+
+ // https://bugzilla.xamarin.com/show_bug.cgi?id=3285
+ [Test]
+ public void Aot_3285 ()
+ {
+ // called as an extension method (always worked)
+ Assert.False (GetType ().GetInterfaces (typeof (IExpectException)).Select (interf => interf != null).FirstOrDefault (), "false");
+
+ // workaround for #3285 - similar to previous fix for monotouch/aot
+ // called as a static method (does not change the result - but it was closer to the original test case)
+ Assert.True (AotExtension.GetInterfaces (GetType (), typeof (IAotTest)).Select (interf => interf != null).FirstOrDefault (delegate { return true; }), "delegate");
+
+ // actual, failing, test case (fixed by inlining code)
+ Assert.True (GetType ().GetInterfaces (typeof (IAotTest)).Select (interf => interf != null).FirstOrDefault (), "FirstOrDefault/true");
+
+ // other similar cases (returning bool with optional predicate delegate)
+ var enumerable = GetType ().GetInterfaces (typeof (IAotTest)).Select (interf => interf != null);
+ Assert.True (enumerable.Any (), "Any");
+ Assert.True (enumerable.ElementAt (0), "ElementAt");
+ Assert.True (enumerable.ElementAtOrDefault (0), "ElementAtOrDefault");
+ Assert.True (enumerable.First (), "First");
+ Assert.True (enumerable.Last (), "Last"); // failed before fix
+ Assert.True (enumerable.LastOrDefault (), "LastOrDefault"); // failed before fix
+ Assert.True (enumerable.Max (), "Max");
+ Assert.True (enumerable.Min (), "Min");
+ Assert.True (enumerable.Single (), "Single"); // failed before fix
+ Assert.True (enumerable.SingleOrDefault (), "SingleOrDefault"); // failed before fix
+ }
+
+ [Test]
+ // https://bugzilla.xamarin.com/show_bug.cgi?id=3444
+ public void ConcurrentDictionary_3444 ()
+ {
+ // note: similar, but simpler, than the original bug report (same exception)
+ var cd = new ConcurrentDictionary ();
+ }
+
+ class SomeObject {
+ public event EventHandler Event;
+
+ public void RaiseEvent ()
+ {
+ var fn = this.Event;
+ if (fn != null)
+ fn (this, EventArgs.Empty);
+ }
+ }
+
+ void OnEvent (object sender, EventArgs e)
+ {
+ }
+
+ [Test]
+ public void EventInfo_3682 ()
+ {
+ var so = new SomeObject ();
+
+ var e = so.GetType ().GetEvent ("Event");
+ if (e != null)
+ e.AddEventHandler (so, new EventHandler (OnEvent));
+ }
+
+ [Test]
+ public void Workaround_3682 ()
+ {
+ var so = new SomeObject ();
+ var e = so.GetType ().GetEvent ("Event");
+ if (e != null) {
+ var add = e.GetAddMethod ();
+ add.Invoke (so, new object[] { new EventHandler(OnEvent) });
+ }
+ }
+
+ class Counseling {
+ public int FK_PERSON;
+
+ public Counseling (int i)
+ {
+ FK_PERSON = i;
+ }
+ }
+
+ class PersonDetail {
+ public int Id;
+
+ public PersonDetail (int i)
+ {
+ Id = i;
+ }
+ }
+
+ class CounselingWithPerson {
+ public Counseling Counseling { get; private set; }
+ public PersonDetail PersonDetail { get; private set; }
+
+ public CounselingWithPerson (Counseling c, PersonDetail p)
+ {
+ Counseling = c;
+ PersonDetail = p;
+ }
+ }
+
+ [Test]
+ public void Linq_Join_3627 ()
+ {
+ List c = new List () {
+ new Counseling (1)
+ };
+ List p = new List () {
+ new PersonDetail (1)
+ };
+ var query = (from wqual in c
+ join personTable in p on wqual.FK_PERSON equals personTable.Id
+ select new CounselingWithPerson (wqual, personTable));
+ Assert.NotNull (query.ToList ());
+ // above throws ExecutionEngineException
+ }
+
+ public void Workaround_3627 ()
+ {
+ List c = new List () {
+ new Counseling (1)
+ };
+ List p = new List () {
+ new PersonDetail (1)
+ };
+ var query = (from wqual in c
+ join personTable in p on wqual.FK_PERSON.ToString () equals personTable.Id.ToString ()
+ select new CounselingWithPerson (wqual, personTable));
+ Assert.NotNull (query.ToList ());
+ }
+
+ public class Foo {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ [Test]
+ public void Linq ()
+ {
+ var list = new List();
+ list.Add (new Foo { Id = 3, Name="def"});
+ list.Add (new Foo { Id = 2, Name="def"});
+ list.Add (new Foo { Id = 1, Name="ggg"});
+ var x = from l in list orderby l.Name, l.Id select l;
+ Assert.That (x.Count (), Is.EqualTo (3), "Count");
+ // above throws ExecutionEngineException
+ }
+
+ [Test]
+ public void Linq_Workaround ()
+ {
+ var list = new List();
+ list.Add (new Foo { Id = 3, Name="def"});
+ list.Add (new Foo { Id = 2, Name="def"});
+ list.Add (new Foo { Id = 1, Name="ggg"});
+ var x = from l in list orderby l.Name, l.Id.ToString () descending select l;
+ }
+
+ [Test]
+ public void SortDescending_3114 ()
+ {
+ List list = new List () {
+ DateTime.Now,
+ DateTime.UtcNow
+ };
+ var result = from datetime in list orderby datetime.Date, datetime.TimeOfDay descending select datetime;
+ // above throws ExecutionEngineException
+ // Attempting to JIT compile method 'System.Linq.OrderedEnumerable`1:CreateOrderedEnumerable (System.Func`2,System.Collections.Generic.IComparer`1,bool)' while running with --aot-only.
+ // .ToString hack does not help in this case :( so it looks even worse
+ }
+
+ [Test]
+ public void Workaround_3114 ()
+ {
+ List