Skip to content

Add unit tests for delegate flags in methods #168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
}
}
1 change: 1 addition & 0 deletions MetadataProcessor.Tests/MetadataProcessor.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<Compile Include="Core\Mono.Cecil\CodeWriterTests.cs" />
<Compile Include="Core\Tables\nanoAssemblyReferenceTableTests.cs" />
<Compile Include="Core\Tables\nanoAttributesTableTests.cs" />
<Compile Include="Core\Tables\nanoMethodDefinitionTableTests.cs" />
<Compile Include="Core\Tables\nanoReferenceTableBaseTests.cs" />
<Compile Include="Core\ClrIntegrationTests.cs" />
<Compile Include="Core\Utility\DumperTests.cs" />
Expand Down
4 changes: 4 additions & 0 deletions MetadataProcessor.Tests/TestNFApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<Compile Include="OneClassOverAll.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestingDelegates.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\mscorlib\nanoFramework.CoreLibrary\CoreLibrary.nfproj" />
Expand Down
72 changes: 72 additions & 0 deletions MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs
Original file line number Diff line number Diff line change
@@ -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!");
}
}
}
18 changes: 18 additions & 0 deletions MetadataProcessor.Tests/TestObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}