2020-10-01 21:27:55 +03:00
using System ;
2017-11-20 16:55:16 +03:00
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using NUnit.Framework ;
using Mono.Cecil ;
using Mono.Cecil.Cil ;
using Xamarin.Tests ;
namespace GeneratorTests
{
[TestFixture ()]
[Parallelizable (ParallelScope.All)]
public class BGenTests
{
[Test]
2020-09-24 15:57:05 +03:00
#if ! NET
2018-02-02 09:09:04 +03:00
[TestCase (Profile.macOSFull)]
2018-05-03 08:31:47 +03:00
[TestCase (Profile.macOSSystem)]
2020-09-24 15:57:05 +03:00
#endif
[TestCase (Profile.macOSMobile)]
2017-11-20 16:55:16 +03:00
public void BMac_Smoke ( Profile profile )
{
BuildFile ( profile , "bmac_smoke.cs" ) ;
}
2020-09-24 15:57:05 +03:00
#if ! NET // There's no System.Drawing in the .NET BCL
2018-05-04 19:02:39 +03:00
[Test]
[TestCase (Profile.macOSSystem)]
public void BMac_NonAbsoluteReference_StillBuilds ( Profile profile )
{
BuildFile ( profile , true , false , new List < string > ( ) { "System.Drawing" } , "bmac_smoke.cs" ) ;
}
2020-09-24 15:57:05 +03:00
#endif
2018-05-04 19:02:39 +03:00
2020-09-24 15:57:05 +03:00
#if ! NET
2018-05-04 19:02:39 +03:00
[Test]
[TestCase (Profile.macOSSystem)]
public void BMac_AbsoluteSystemReference_StillBuilds ( Profile profile )
{
BuildFile ( profile , true , false , new List < string > ( ) { "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/System.Drawing.dll" } , "bmac_smoke.cs" ) ;
}
2020-09-24 15:57:05 +03:00
#endif
2018-05-04 19:02:39 +03:00
2017-11-20 16:55:16 +03:00
[Test]
2020-09-24 15:57:05 +03:00
#if ! NET
2018-02-02 09:09:04 +03:00
[TestCase (Profile.macOSFull)]
2018-05-03 08:31:47 +03:00
[TestCase (Profile.macOSSystem)]
2020-09-24 15:57:05 +03:00
#endif
[TestCase (Profile.macOSMobile)]
2017-11-20 16:55:16 +03:00
public void BMac_With_Hyphen_In_Name ( Profile profile )
{
BuildFile ( profile , "bmac-with-hyphen-in-name.cs" ) ;
}
[Test]
2020-09-24 15:57:05 +03:00
#if ! NET
2018-02-02 09:09:04 +03:00
[TestCase (Profile.macOSFull)]
2018-05-03 08:31:47 +03:00
[TestCase (Profile.macOSSystem)]
2020-09-24 15:57:05 +03:00
#endif
[TestCase (Profile.macOSMobile)]
2017-11-20 16:55:16 +03:00
public void PropertyRedefinitionMac ( Profile profile )
{
BuildFile ( profile , "property-redefination-mac.cs" ) ;
}
[Test]
2020-09-24 15:57:05 +03:00
#if ! NET
2018-02-02 09:09:04 +03:00
[TestCase (Profile.macOSFull)]
2018-05-03 08:31:47 +03:00
[TestCase (Profile.macOSSystem)]
2020-09-24 15:57:05 +03:00
#endif
[TestCase (Profile.macOSMobile)]
2017-11-20 16:55:16 +03:00
public void NSApplicationPublicEnsureMethods ( Profile profile )
{
BuildFile ( profile , "NSApplicationPublicEnsureMethods.cs" ) ;
}
[Test]
2020-09-24 15:57:05 +03:00
#if ! NET
2018-02-02 09:09:04 +03:00
[TestCase (Profile.macOSFull)]
2018-05-03 08:31:47 +03:00
[TestCase (Profile.macOSSystem)]
2020-09-24 15:57:05 +03:00
#endif
[TestCase (Profile.macOSMobile)]
2017-11-20 16:55:16 +03:00
public void ProtocolDuplicateAbstract ( Profile profile )
{
BuildFile ( profile , "protocol-duplicate-abstract.cs" ) ;
}
[Test]
public void Bug15283 ( )
{
BuildFile ( Profile . iOS , "bug15283.cs" ) ;
}
[Test]
public void Bug15307 ( )
{
BuildFile ( Profile . iOS , "bug15307.cs" ) ;
}
2021-04-10 18:09:14 +03:00
#if ! NET
// error BI1055: bgen: Internal error: failed to convert type 'System.Runtime.Versioning.SupportedOSPlatformAttribute, System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.
2017-11-20 16:55:16 +03:00
[Test]
public void Bug15799 ( )
{
BuildFile ( Profile . iOS , "bug15799.cs" ) ;
}
2021-04-10 18:09:14 +03:00
#endif
2017-11-20 16:55:16 +03:00
[Test]
public void Bug16036 ( )
{
BuildFile ( Profile . iOS , "bug16036.cs" ) ;
}
[Test]
public void Bug17232 ( )
{
BuildFile ( Profile . iOS , "bug17232.cs" ) ;
}
2021-04-10 18:09:14 +03:00
#if ! NET
// error BI1055: bgen: Internal error: failed to convert type 'System.Runtime.Versioning.SupportedOSPlatformAttribute, System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.
2017-11-20 16:55:16 +03:00
[Test]
public void Bug23041 ( )
{
BuildFile ( Profile . iOS , "bug23041.cs" ) ;
}
2021-04-10 18:09:14 +03:00
#endif
2017-11-20 16:55:16 +03:00
[Test]
public void Bug24078 ( )
{
BuildFile ( Profile . iOS , "bug24078-ignore-methods-events.cs" ) ;
}
[Test]
public void Bug27428 ( )
{
BuildFile ( Profile . iOS , "bug27428.cs" ) ;
}
[Test]
public void Bug27430 ( )
{
BuildFile ( Profile . iOS , "bug27430.cs" ) ;
}
[Test]
public void Bug27986 ( )
{
var bgen = BuildFile ( Profile . iOS , false , "bug27986.cs" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMembers = ( ( IEnumerable < ICustomAttributeProvider > ) allTypes )
. Union ( allTypes . SelectMany ( ( type ) = > type . Methods ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Fields ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Properties ) ) ;
var preserves = allMembers . Count ( ( v ) = > v . HasCustomAttributes & & v . CustomAttributes . Any ( ( ca ) = > ca . AttributeType . Name = = "PreserveAttribute" ) ) ;
Assert . AreEqual ( 28 , preserves , "Preserve attribute count" ) ; // If you modified code that generates PreserveAttributes please update the preserve count
}
[Test]
public void Bug29493 ( )
{
var bgen = BuildFile ( Profile . iOS , false , "bug29493.cs" ) ;
// Check that there is no call to Class.GetHandle with a "global::"-prefixed string
foreach ( var method in bgen . ApiAssembly . MainModule . GetTypes ( ) . SelectMany ( ( v ) = > v . Methods ) ) {
if ( ! method . HasBody )
continue ;
var instructions = method . Body . Instructions ;
foreach ( var ins in instructions ) {
if ( ins . OpCode . FlowControl ! = FlowControl . Call )
continue ;
var mr = ( MethodReference ) ins . Operand ;
if ( mr . DeclaringType . Namespace ! = "ObjCRuntime" & & mr . DeclaringType . Name ! = "Class" )
continue ;
if ( mr . Name ! = "GetHandle" & & mr . Name ! = "GetHandleIntrinsic" )
continue ;
var str = ( string ) ins . Previous . Operand ;
if ( str . StartsWith ( "global::" , StringComparison . Ordinal ) )
Assert . Fail ( $"Found a call to Class.GetHandle with an invalid ('global::'-prefixed) string in {method.FullName} at offset {ins.Offset}.\n\t{string.Join (" \ n \ t ", instructions)}" ) ;
}
}
}
[Test]
2020-09-24 15:57:05 +03:00
#if ! NET
2018-02-02 09:09:04 +03:00
[TestCase (Profile.macOSFull)]
2018-05-03 08:31:47 +03:00
[TestCase (Profile.macOSSystem)]
2020-09-24 15:57:05 +03:00
#endif
[TestCase (Profile.macOSMobile)]
2018-01-04 00:41:49 +03:00
public void Bug31788 ( Profile profile )
2017-11-20 16:55:16 +03:00
{
var bgen = new BGenTool ( ) ;
2018-01-04 00:41:49 +03:00
bgen . Profile = profile ;
2017-11-20 16:55:16 +03:00
bgen . Defines = BGenTool . GetDefaultDefines ( bgen . Profile ) ;
bgen . CreateTemporaryBinding ( File . ReadAllText ( Path . Combine ( Configuration . SourceRoot , "tests" , "generator" , "bug31788.cs" ) ) ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertNoWarnings ( ) ;
bgen . AssertApiCallsMethod ( "Test" , "MarshalInProperty" , "get_Shared" , "xamarin_IntPtr_objc_msgSend" , "MarshalInProperty.Shared getter" ) ;
bgen . AssertApiCallsMethod ( "Test" , "MarshalOnProperty" , "get_Shared" , "xamarin_IntPtr_objc_msgSend" , "MarshalOnProperty.Shared getter" ) ;
}
[Test]
public void Bug34042 ( )
{
BuildFile ( Profile . iOS , "bug34042.cs" ) ;
}
[Test]
public void Bug35176 ( )
{
var bgen = BuildFile ( Profile . iOS , "bug35176.cs" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMembers = ( ( IEnumerable < ICustomAttributeProvider > ) allTypes )
. Union ( allTypes . SelectMany ( ( type ) = > type . Methods ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Fields ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Properties ) ) ;
2021-04-10 18:09:14 +03:00
#if NET
const string attrib = "SupportedOSPlatformAttribute" ;
#else
const string attrib = "IntroducedAttribute" ;
#endif
var preserves = allMembers . Sum ( ( v ) = > v . CustomAttributes . Count ( ( ca ) = > ca . AttributeType . Name = = attrib ) ) ;
2021-03-01 16:39:52 +03:00
Assert . AreEqual ( 10 , preserves , "Introduced attribute count" ) ; // If you modified code that generates IntroducedAttributes please update the attribute count
2017-11-20 16:55:16 +03:00
}
[Test]
public void Bug36457 ( )
{
BuildFile ( Profile . iOS , "bug36457.cs" ) ;
}
[Test]
public void Bug39614 ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . AddTestApiDefinition ( "bug39614.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertWarning ( 1103 , "'FooType`1' does not live under a namespace; namespaces are a highly recommended .NET best practice" ) ;
}
[Test]
public void Bug40282 ( )
{
BuildFile ( Profile . iOS , "bug40282.cs" ) ;
}
[Test]
public void Bug42742 ( )
{
var bgen = BuildFile ( Profile . iOS , "bug42742.cs" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMembers = ( ( IEnumerable < ICustomAttributeProvider > ) allTypes )
. Union ( allTypes . SelectMany ( ( type ) = > type . Methods ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Fields ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Properties ) ) ;
var preserves = allMembers . Sum ( ( v ) = > v . CustomAttributes . Count ( ( ca ) = > ca . AttributeType . Name = = "AdviceAttribute" ) ) ;
Assert . AreEqual ( 24 , preserves , "Advice attribute count" ) ; // If you modified code that generates AdviceAttributes please update the attribute count
}
[Test]
public void Bug43579 ( )
{
BuildFile ( Profile . iOS , "bug43579.cs" ) ;
}
[Test]
public void Bug46292 ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . ProcessEnums = true ;
bgen . AddTestApiDefinition ( "bug46292.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMembers = ( ( IEnumerable < ICustomAttributeProvider > ) allTypes )
. Union ( allTypes . SelectMany ( ( type ) = > type . Methods ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Fields ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Properties ) ) ;
var attribCount = allMembers . Count ( ( v ) = > v . HasCustomAttributes & & v . CustomAttributes . Any ( ( ca ) = > ca . AttributeType . Name = = "ObsoleteAttribute" ) ) ;
Assert . AreEqual ( 2 , attribCount , "attribute count" ) ;
}
[Test]
public void Bug53076 ( )
{
var bgen = BuildFile ( Profile . iOS , "bug53076.cs" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMethods = bgen . ApiAssembly . MainModule . GetTypes ( ) . SelectMany ( ( type ) = > type . Methods ) ;
// Count all *Async methods whose first parameter is 'IMyFooProtocol'.
var methodCount = allMethods . Count ( ( v ) = > v . Name . EndsWith ( "Async" , StringComparison . Ordinal ) & & v . Parameters . Count > 0 & & v . Parameters [ 0 ] . ParameterType . Name = = "IMyFooProtocol" ) ;
Assert . AreEqual ( 10 , methodCount , "Async method count" ) ;
}
[Test]
public void Bug53076WithModel ( )
{
var bgen = BuildFile ( Profile . iOS , "bug53076withmodel.cs" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMethods = bgen . ApiAssembly . MainModule . GetTypes ( ) . SelectMany ( ( type ) = > type . Methods ) ;
// Count all *Async methods whose first parameter is 'IMyFooProtocol'.
var methodCount = allMethods . Count ( ( v ) = > v . Name . EndsWith ( "Async" , StringComparison . Ordinal ) & & v . Parameters . Count > 0 & & v . Parameters [ 0 ] . ParameterType . Name = = "IMyFooProtocol" ) ;
Assert . AreEqual ( 10 , methodCount , "Async method count" ) ;
}
2021-04-10 18:09:14 +03:00
#if ! NET
// error BI1055: bgen: Internal error: failed to convert type 'System.Runtime.Versioning.SupportedOSPlatformAttribute, System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.
2017-11-20 16:55:16 +03:00
[Test]
public void StackOverflow20696157 ( )
{
BuildFile ( Profile . iOS , "sof20696157.cs" ) ;
}
2021-04-10 18:09:14 +03:00
#endif
2017-11-20 16:55:16 +03:00
[Test]
public void HyphenInName ( )
{
BuildFile ( Profile . iOS , "btouch-with-hyphen-in-name.cs" ) ;
}
[Test]
public void PropertyRedefinition ( )
{
BuildFile ( Profile . iOS , "property-redefination-ios.cs" ) ;
}
[Test]
public void ArrayFromHandleBug ( )
{
BuildFile ( Profile . iOS , "arrayfromhandlebug.cs" ) ;
}
[Test]
public void StrongDictSupportTemplatedDicts ( )
{
BuildFile ( Profile . iOS , "strong-dict-support-templated-dicts.cs" ) ;
}
[Test]
public void GenericStrongDictionary ( )
{
BuildFile ( Profile . iOS , "generic-strong-dictionary.cs" ) ;
}
[Test]
public void BindAsTests ( )
{
BuildFile ( Profile . iOS , "bindastests.cs" ) ;
}
[Test]
public void Forum54078 ( )
{
var bgen = BuildFile ( Profile . iOS , "forum54078.cs" ) ;
var api = bgen . ApiAssembly ;
var type = api . MainModule . GetType ( "Test" , "CustomController" ) ;
foreach ( var method in type . Methods )
Asserts . DoesNotThrowExceptions ( method , type . FullName ) ;
}
[Test]
public void Desk63279 ( )
{
BuildFile ( Profile . iOS , "desk63279A.cs" , "desk63279B.cs" ) ;
}
[Test]
public void Desk79124 ( )
{
var bgen = BuildFile ( Profile . iOS , "desk79124.cs" ) ;
bgen . AssertType ( "Desk79124.WYPopoverBackgroundView/WYPopoverBackgroundViewAppearance" ) ;
}
[Test]
public void MultipleApiDefinitions1 ( )
{
BuildFile ( Profile . iOS , "multiple-api-definitions1.cs" ) ;
}
[Test]
public void MultipleApiDefinitions2 ( )
{
BuildFile ( Profile . iOS , "multiple-api-definitions2-a.cs" , "multiple-api-definitions2-b.cs" ) ;
}
[Test]
public void ClassNameCollision ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . Defines = BGenTool . GetDefaultDefines ( bgen . Profile ) ;
bgen . Sources . Add ( Path . Combine ( Configuration . SourceRoot , "tests" , "generator" , "classNameCollision-enum.cs" ) ) ;
bgen . ApiDefinitions . Add ( Path . Combine ( Configuration . SourceRoot , "tests" , "generator" , "classNameCollision.cs" ) ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertNoWarnings ( ) ;
}
[Test]
public void VirtualWrap ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . AddTestApiDefinition ( "virtualwrap.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . ProcessEnums = true ;
bgen . AssertExecute ( "build" ) ;
// verify virtual methods
var attribs = MethodAttributes . Public | MethodAttributes . Virtual | MethodAttributes . HideBySig | MethodAttributes . NewSlot ;
bgen . AssertMethod ( "WrapTest.MyFooClass" , "FromUrl" , attribs , null , "Foundation.NSUrl" ) ;
bgen . AssertMethod ( "WrapTest.MyFooClass" , "FromUrl" , attribs , null , "System.String" ) ;
bgen . AssertMethod ( "WrapTest.MyFooClass" , "get_FooNSString" , attribs | MethodAttributes . SpecialName , "Foundation.NSString" ) ;
bgen . AssertMethod ( "WrapTest.MyFooClass" , "get_FooString" , attribs | MethodAttributes . SpecialName , "System.String" ) ;
// verify non-virtual methods
attribs = MethodAttributes . Public | MethodAttributes . HideBySig ;
bgen . AssertMethod ( "WrapTest.MyFooClass" , "FromUrlN" , attribs , null , "System.String" ) ;
bgen . AssertMethod ( "WrapTest.MyFooClass" , "get_FooNSStringN" , attribs | MethodAttributes . SpecialName , "Foundation.NSString" ) ;
}
[Test]
public void NoAsyncInternalWrapper ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . AddTestApiDefinition ( "noasyncinternalwrapper.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
var allTypes = bgen . ApiAssembly . MainModule . GetTypes ( ) . ToArray ( ) ;
var allMembers = ( ( IEnumerable < MemberReference > ) allTypes )
. Union ( allTypes . SelectMany ( ( type ) = > type . Methods ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Fields ) )
. Union ( allTypes . SelectMany ( ( type ) = > type . Properties ) ) ;
Assert . AreEqual ( 1 , allMembers . Count ( ( member ) = > member . Name = = "RequiredMethodAsync" ) , "Expected 1 RequiredMethodAsync members in generated code. If you modified code that generates RequiredMethodAsync (AsyncAttribute) please update the RequiredMethodAsync count." ) ;
var attribs = MethodAttributes . Public | MethodAttributes . Static | MethodAttributes . HideBySig ;
bgen . AssertMethod ( "NoAsyncInternalWrapperTests.MyFooDelegate_Extensions" , "RequiredMethodAsync" , attribs , "System.Threading.Tasks.Task" , "NoAsyncInternalWrapperTests.IMyFooDelegate" , "System.Int32" ) ;
}
[Test]
public void NoAsyncWarningCS0219 ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . AddTestApiDefinition ( "noasyncwarningcs0219.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertNoWarnings ( ) ;
}
[Test]
public void FieldEnumTests ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . ProcessEnums = true ;
bgen . AddTestApiDefinition ( "fieldenumtests.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertNoWarnings ( ) ;
}
[Test]
public void SmartEnumWithFramework ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . ProcessEnums = true ;
bgen . AddTestApiDefinition ( "smartenumwithframework.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertApiLoadsField ( "SmartEnumWithFramework.FooEnumTestExtensions" , "get_First" , "ObjCRuntime.Libraries/CoreImage" , "Handle" , "First getter" ) ;
bgen . AssertApiLoadsField ( "SmartEnumWithFramework.FooEnumTestExtensions" , "get_Second" , "ObjCRuntime.Libraries/CoreImage" , "Handle" , "Second getter" ) ;
}
[Test]
public void ForcedType ( )
{
var bgen = BuildFile ( Profile . iOS , false , "forcedtype.cs" ) ;
var allMethods = bgen . ApiAssembly . MainModule . GetTypes ( ) . SelectMany ( ( type ) = > type . Methods ) ;
// Count the number of calls to GetINativeObject
var getINativeObjectCalls = allMethods . Sum ( ( method ) = > {
if ( ! method . HasBody )
return 0 ;
return method . Body . Instructions . Count ( ( ins ) = > {
if ( ins . OpCode . FlowControl ! = FlowControl . Call )
return false ;
var mr = ( MethodReference ) ins . Operand ;
return mr . Name = = "GetINativeObject" ;
} ) ;
} ) ;
Assert . AreEqual ( 12 , getINativeObjectCalls , "Preserve attribute count" ) ; // If you modified code that generates PreserveAttributes please update the preserve count
}
2017-12-01 17:18:20 +03:00
[Test]
public void IsDirectBinding ( )
{
var bgen = BuildFile ( Profile . iOS , "tests/is-direct-binding.cs" ) ;
var callsMethod = new Func < MethodDefinition , string , bool > ( ( method , name ) = > {
return method . Body . Instructions . Any ( ( ins ) = > {
switch ( ins . OpCode . Code ) {
case Code . Call :
case Code . Calli :
case Code . Callvirt :
var mr = ins . Operand as MethodReference ;
return mr . Name = = name ;
default :
return false ;
}
} ) ;
} ) ;
// The normal constructor should get the IsDirectBinding value, and call both objc_msgSend and objc_msgSendSuper
var cConstructor = bgen . ApiAssembly . MainModule . GetType ( "NS" , "C" ) . Methods . First ( ( v ) = > v . IsConstructor & & ! v . HasParameters & & ! v . IsStatic ) ;
Assert . That ( callsMethod ( cConstructor , "set_IsDirectBinding" ) , "C: set_IsDirectBinding" ) ;
Assert . That ( callsMethod ( cConstructor , "get_IsDirectBinding" ) , "C: get_IsDirectBinding" ) ;
Assert . That ( callsMethod ( cConstructor , "IntPtr_objc_msgSend" ) , "C: objc_msgSend" ) ;
Assert . That ( callsMethod ( cConstructor , "IntPtr_objc_msgSendSuper" ) , "C: objc_msgSendSuper" ) ;
// The constructor for a model should not get the IsDirectBinding value, because it's always 'false'. Neither should it call objc_msgSend, only objc_msgSendSuper
var pConstructor = bgen . ApiAssembly . MainModule . GetType ( "NS" , "P" ) . Methods . First ( ( v ) = > v . IsConstructor & & ! v . HasParameters & & ! v . IsStatic ) ;
Assert . That ( callsMethod ( pConstructor , "set_IsDirectBinding" ) , "P: set_IsDirectBinding" ) ;
Assert . That ( ! callsMethod ( pConstructor , "get_IsDirectBinding" ) , "P: get_IsDirectBinding" ) ;
Assert . That ( ! callsMethod ( pConstructor , "IntPtr_objc_msgSend" ) , "P: objc_msgSend" ) ;
Assert . That ( callsMethod ( pConstructor , "IntPtr_objc_msgSendSuper" ) , "P: objc_msgSendSuper" ) ;
// The constructor for a sealed class should not get the IsDirectBinding value, because it's always true. Neither should it call objc_msgSendSuper, only objc_msgSend.
var sConstructor = bgen . ApiAssembly . MainModule . GetType ( "NS" , "S" ) . Methods . First ( ( v ) = > v . IsConstructor & & ! v . HasParameters & & ! v . IsStatic ) ;
Assert . That ( callsMethod ( sConstructor , "set_IsDirectBinding" ) , "S: set_IsDirectBinding" ) ;
Assert . That ( ! callsMethod ( sConstructor , "get_IsDirectBinding" ) , "S: get_IsDirectBinding" ) ;
Assert . That ( callsMethod ( sConstructor , "IntPtr_objc_msgSend" ) , "S: objc_msgSend" ) ;
Assert . That ( ! callsMethod ( sConstructor , "IntPtr_objc_msgSendSuper" ) , "S: objc_msgSendSuper" ) ;
}
2018-01-16 16:41:25 +03:00
[Test]
public void Bug57531 ( ) = > BuildFile ( Profile . iOS , "bug57531.cs" ) ;
2018-02-06 06:14:08 +03:00
[Test]
public void Bug57870 ( ) = > BuildFile ( Profile . iOS , true , true , "bug57870.cs" ) ;
2018-04-06 20:42:14 +03:00
[Test]
public void GHIssue3869 ( ) = > BuildFile ( Profile . iOS , "ghissue3869.cs" ) ;
2018-04-06 18:24:07 +03:00
[Test]
[TestCase ("issue3875.cs", "AProtocol")]
[TestCase ("issue3875B.cs", "BProtocol")]
[TestCase ("issue3875C.cs", "api0__Issue3875_AProtocol")]
public void Issue3875 ( string file , string modelName )
{
var bgen = BuildFile ( Profile . iOS , file ) ;
var attrib = bgen . ApiAssembly . MainModule . GetType ( "Issue3875" , "AProtocol" ) . CustomAttributes . Where ( ( v ) = > v . AttributeType . Name = = "RegisterAttribute" ) . First ( ) ;
Assert . AreEqual ( modelName , attrib . ConstructorArguments [ 0 ] . Value , "Custom ObjC name" ) ;
}
2019-01-22 17:52:39 +03:00
[Test]
public void GHIssue5444 ( ) = > BuildFile ( Profile . iOS , "ghissue5444.cs" ) ;
2019-01-24 16:57:46 +03:00
[Test]
public void GH5416_method ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . AddTestApiDefinition ( "ghissue5416b.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertWarning ( 1118 , "[NullAllowed] should not be used on methods, like 'NSString Method(Foundation.NSDate, Foundation.NSObject)', but only on properties, parameters and return values." ) ;
}
[Test]
public void GH5416_setter ( )
{
var bgen = new BGenTool ( ) ;
bgen . Profile = Profile . iOS ;
bgen . AddTestApiDefinition ( "ghissue5416a.cs" ) ;
bgen . CreateTemporaryBinding ( ) ;
bgen . AssertExecute ( "build" ) ;
bgen . AssertWarning ( 1118 , "[NullAllowed] should not be used on methods, like 'Void set_Setter(Foundation.NSString)', but only on properties, parameters and return values." ) ;
}
2019-03-04 16:13:34 +03:00
[Test]
public void GHIssue5692 ( ) = > BuildFile ( Profile . iOS , "ghissue5692.cs" ) ;
2019-10-26 03:06:00 +03:00
[Test]
2020-09-24 15:57:05 +03:00
public void GHIssue7304 ( ) = > BuildFile ( Profile . macOSMobile , "ghissue7304.cs" ) ;
2019-10-26 03:06:00 +03:00
2019-05-28 09:08:45 +03:00
[Test]
2019-04-23 09:15:49 +03:00
public void RefOutParameters ( )
{
BuildFile ( Profile . macOSMobile , true , "tests/ref-out-parameters.cs" ) ;
2019-05-28 09:08:45 +03:00
}
2019-04-23 09:15:49 +03:00
2019-05-28 09:08:45 +03:00
[Test]
public void ReturnRelease ( )
{
BuildFile ( Profile . iOS , "tests/return-release.cs" ) ;
2019-04-23 09:15:49 +03:00
}
2019-07-24 14:28:07 +03:00
[Test]
public void GHIssue6626 ( ) = > BuildFile ( Profile . iOS , "ghissue6626.cs" ) ;
2019-08-14 01:36:36 +03:00
[Test]
public void StrongDictsNativeEnums ( ) = > BuildFile ( Profile . iOS , "strong-dict-native-enum.cs" ) ;
2019-08-26 17:14:26 +03:00
[Test]
public void VSTS970507 ( )
{
BuildFile ( Profile . iOS , "tests/vsts-970507.cs" ) ;
}
2019-09-11 15:12:43 +03:00
[Test]
public void DiamondProtocol ( )
{
BuildFile ( Profile . iOS , "tests/diamond-protocol.cs" ) ;
}
2020-10-06 05:01:36 +03:00
[Test]
public void GHIssue9065_Sealed ( ) = > BuildFile ( Profile . iOS , nowarnings : true , "ghissue9065.cs" ) ;
2017-11-20 16:55:16 +03:00
BGenTool BuildFile ( Profile profile , params string [ ] filenames )
{
2018-02-06 06:14:08 +03:00
return BuildFile ( profile , true , false , filenames ) ;
2017-11-20 16:55:16 +03:00
}
BGenTool BuildFile ( Profile profile , bool nowarnings , params string [ ] filenames )
2018-02-06 06:14:08 +03:00
{
return BuildFile ( profile , nowarnings , false , filenames ) ;
}
BGenTool BuildFile ( Profile profile , bool nowarnings , bool processEnums , params string [ ] filenames )
2018-05-04 19:02:39 +03:00
{
return BuildFile ( profile , nowarnings , processEnums , Enumerable . Empty < string > ( ) , filenames ) ;
}
BGenTool BuildFile ( Profile profile , bool nowarnings , bool processEnums , IEnumerable < string > references , params string [ ] filenames )
2017-11-20 16:55:16 +03:00
{
var bgen = new BGenTool ( ) ;
bgen . Profile = profile ;
2018-02-06 06:14:08 +03:00
bgen . ProcessEnums = processEnums ;
2017-11-20 16:55:16 +03:00
bgen . Defines = BGenTool . GetDefaultDefines ( bgen . Profile ) ;
2018-05-04 19:02:39 +03:00
bgen . References = references . ToList ( ) ;
2018-03-27 22:31:27 +03:00
TestContext . Out . WriteLine ( TestContext . CurrentContext . Test . FullName ) ;
foreach ( var filename in filenames )
TestContext . Out . WriteLine ( $"\t{filename}" ) ;
2017-11-20 16:55:16 +03:00
bgen . CreateTemporaryBinding ( filenames . Select ( ( filename ) = > File . ReadAllText ( Path . Combine ( Configuration . SourceRoot , "tests" , "generator" , filename ) ) ) . ToArray ( ) ) ;
bgen . AssertExecute ( "build" ) ;
if ( nowarnings )
bgen . AssertNoWarnings ( ) ;
return bgen ;
}
}
}