diff --git a/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs b/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs new file mode 100644 index 00000000..d673e4d2 --- /dev/null +++ b/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs @@ -0,0 +1,79 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Mono.Cecil; + +namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables +{ + [TestClass] + public class nanoMethodDefinitionTableTests + { + private TypeDefinition _testDelegatesClassTypeDefinition; + + [TestInitialize] + public void Setup() + { + var nanoTablesContext = TestObjectHelper.GetTestNFAppNanoTablesContext(); + _testDelegatesClassTypeDefinition = TestObjectHelper.GetTestNFAppTestingDelegatesTypeDefinition(nanoTablesContext.AssemblyDefinition); + } + + #region delegate method flags + + [TestMethod] + public void TestDelegateInvokeMethodReturnsDelegateInvokeFlag() + { + var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", "Invoke"); + + uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition); + + // Assert + const uint expectedFlag = 0x00020000; // MD_DelegateInvoke + Assert.AreEqual(expectedFlag, flags & expectedFlag); + } + + [TestMethod] + public void TestDelegateConstructorMethodReturnsDelegateConstructorFlag() + { + var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", ".ctor"); + + uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition); + + // Assert + const uint expectedFlag = 0x00010000; // MD_DelegateConstructor + Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for Delegate constructor."); + } + + [TestMethod] + public void TestDelegateBeginInvokeMethodReturnsDelegateBeginInvokeFlag() + { + // Arrange + var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", "BeginInvoke"); + + // Act + uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition); + + // Assert + const uint expectedFlag = 0x00040000; // MD_DelegateBeginInvoke + Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for BeginInvoke method."); + } + + [TestMethod] + public void TestDelegateEndInvokeMethodReturnsDelegateEndInvokeFlag() + { + // Arrange + var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", "EndInvoke"); + + // Act + uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition); + + // Assert + const uint expectedFlag = 0x00080000; // MD_DelegateEndInvoke + Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for EndInvoke method."); + } + + #endregion + } +} diff --git a/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj b/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj index 499aac97..1578d3aa 100644 --- a/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj +++ b/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj @@ -60,6 +60,7 @@ + diff --git a/MetadataProcessor.Tests/TestNFApp/Program.cs b/MetadataProcessor.Tests/TestNFApp/Program.cs index 443706de..ac164377 100644 --- a/MetadataProcessor.Tests/TestNFApp/Program.cs +++ b/MetadataProcessor.Tests/TestNFApp/Program.cs @@ -37,6 +37,10 @@ public static void Main() // Reflection Tests ReflectionTests(); + /////////////////////////////////////// + // Delegate and MulticastDelegate tests + _ = new TestingDelegates(); + //////////////////////////////////////////////// // Test enum in another assembly, same namespace var enumTest = new TestEnumInAnotherAssembly(); diff --git a/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj b/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj index 927995f6..601594f3 100644 --- a/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj +++ b/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj @@ -32,6 +32,7 @@ + diff --git a/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs b/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs new file mode 100644 index 00000000..8f432977 --- /dev/null +++ b/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs @@ -0,0 +1,72 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +using System; + +namespace TestNFApp +{ + public class TestingDelegates + { + public TestingDelegates() + { + DelegateTests(); + MulticastDelegateTests(); + } + + // Define a delegate + public delegate void SimpleDelegate(string message); + + // Method that matches the delegate signature + public void DisplayMessage(string message) + { + Console.WriteLine(message); + } + + // Another method that matches the delegate signature + public void DisplayUpperCaseMessage(string message) + { + Console.WriteLine("Uppercase: " + message.ToUpper()); + } + + // Another method that matches the delegate signature + public void DisplayLowerCaseMessage(string message) + { + Console.WriteLine("Lowercase: " + message.ToLower()); + } + + private void DelegateTests() + { + // Instantiate the delegate + SimpleDelegate del = new SimpleDelegate(DisplayMessage); + + // Call the delegate + del("Hello, this is a delegate example!"); + + // Using delegate with anonymous method + SimpleDelegate del2 = delegate (string msg) + { + Console.WriteLine(msg); + }; + + del2("Hello, this is a delegate example called from an anonymous method!"); + + // Using delegate with lambda expression + SimpleDelegate del3 = (msg) => Console.WriteLine(msg); + + del3("Hello, this is a delegate example called from a lambda expression!"); + } + + private void MulticastDelegateTests() + { + // Instantiate the delegate with multiple methods + SimpleDelegate del = DisplayMessage; + del += DisplayUpperCaseMessage; + del += DisplayLowerCaseMessage; + + // Call the multicast delegate + del("Hello, this is a multicast delegate example!"); + } + } +} diff --git a/MetadataProcessor.Tests/TestObjectHelper.cs b/MetadataProcessor.Tests/TestObjectHelper.cs index 5cd35b16..863e875d 100644 --- a/MetadataProcessor.Tests/TestObjectHelper.cs +++ b/MetadataProcessor.Tests/TestObjectHelper.cs @@ -375,5 +375,23 @@ public static void AdjustMethodBodyOffsets(Mono.Cecil.Cil.MethodBody methodBody) } } + internal static TypeDefinition GetTestNFAppTestingDelegatesTypeDefinition(AssemblyDefinition assemblyDefinition) + { + TypeDefinition ret = null; + + var module = assemblyDefinition.Modules[0]; + ret = module.Types.First(i => i.FullName == "TestNFApp.TestingDelegates"); + + return ret; + } + + internal static MethodDefinition GetMethodDefinition( + TypeDefinition typeDefinition, + string delegateName, + string methodName) + { + var delegateType = typeDefinition.NestedTypes.First(nt => nt.Name == delegateName); + return delegateType.Methods.First(m => m.Name == methodName); + } } }