2021-08-11 11:06:46 +03:00
using System ;
2021-04-13 22:48:20 +03:00
using System.Collections.Generic ;
2020-02-26 23:03:59 +03:00
using System.Reflection ;
using System.Runtime.CompilerServices ;
using NUnit.Framework ;
using Xamarin.Utils ;
using Foundation ;
using ObjCRuntime ;
namespace Introspection {
[TestFixture]
// we want the tests to be available because we use the linker
[Preserve (AllMembers = true)]
public class ApiTypeTest : ApiBaseTest {
bool Skip ( Type type )
{
switch ( type . Namespace ) {
2022-08-05 18:51:11 +03:00
#if __IOS__ | | __WATCHOS__
2020-02-26 23:03:59 +03:00
// running the .cctor on the simulator works... but makes some other CoreNFC intro tests fail later
// we'll still get the results from device tests
case "CoreNFC" :
case "DeviceCheck" :
// we can't call the `NFCNdefReaderSession.ReadingAvailable` API on 32bits (PlatformNotSupportedException)
// and if we call it then the .cctor is executed and we get the same failures :()
2021-12-16 00:32:14 +03:00
return ( ( IntPtr . Size = = 4 ) | | TestRuntime . IsSimulatorOrDesktop ) ;
2023-04-21 19:48:22 +03:00
#endif
#if __MACCATALYST__
case "AddressBook" :
// The AddressBook framework is sometimes missing from Mac Catalyst, causing:
// [FAIL] AddressBook.InitConstants .cctor could not execute properly: System.TypeInitializationException: The type initializer for 'AddressBook.InitConstants' threw an exception.
// ---> System.EntryPointNotFoundException: ABAddressBookCreate
// but I wasn't able to reproduce this locally, only on the bots (so only disable this in the tests, and not change the API, since it's still working for me).
return true ;
2020-02-26 23:03:59 +03:00
#endif
default :
return false ;
}
}
[Test]
public void StaticCtor ( )
{
2021-04-13 22:48:20 +03:00
var issues = new HashSet < string > ( ) ;
2020-02-26 23:03:59 +03:00
ContinueOnFailure = true ;
foreach ( Type t in Assembly . GetTypes ( ) ) {
if ( Skip ( t ) )
continue ;
var cctor = t . GetConstructor ( BindingFlags . Static | BindingFlags . NonPublic , null , Type . EmptyTypes , null ) ;
2023-05-05 18:52:19 +03:00
if ( cctor is null )
2020-02-26 23:03:59 +03:00
continue ;
// we don't skip based on availability attributes since the execution of .cctor can easily happen indirectly and
// we rather catch them all here *now* than trying to figure out how to replicate the specific conditions *later*
try {
RuntimeHelpers . RunClassConstructor ( t . TypeHandle ) ;
2022-11-07 17:20:26 +03:00
} catch ( TypeInitializationException e ) {
2021-04-13 22:48:20 +03:00
issues . Add ( t . FullName ) ;
2020-02-26 23:03:59 +03:00
ReportError ( $"{t.FullName} .cctor could not execute properly: {e}" ) ;
}
}
2021-04-13 22:48:20 +03:00
AssertIfErrors ( $"{Errors} execution failure(s): " + String . Join ( ',' , issues ) ) ;
2020-02-26 23:03:59 +03:00
}
}
2021-08-11 11:06:46 +03:00
}