Skip to content

Commit c7d23e6

Browse files
committed
Add unit tests for delegate flags in methods
1 parent fc23448 commit c7d23e6

File tree

6 files changed

+221
-0
lines changed

6 files changed

+221
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
using Mono.Cecil;
8+
9+
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
10+
{
11+
[TestClass]
12+
public class nanoMethodDefinitionTableTests
13+
{
14+
private TypeDefinition _testDelegatesClassTypeDefinition;
15+
16+
[TestInitialize]
17+
public void Setup()
18+
{
19+
var nanoTablesContext = TestObjectHelper.GetTestNFAppNanoTablesContext();
20+
_testDelegatesClassTypeDefinition = TestObjectHelper.GetTestNFAppTestingDelegatesTypeDefinition(nanoTablesContext.AssemblyDefinition);
21+
}
22+
23+
[TestMethod]
24+
public void GetFlags_PrivateMethod_ReturnsPrivateFlag()
25+
{
26+
var nanoTablesContext = TestObjectHelper.GetTestNFAppNanoTablesContext();
27+
var testDelegatesClassTypeDefinition = TestObjectHelper.GetTestNFAppTestingDelegatesTypeDefinition(nanoTablesContext.AssemblyDefinition);
28+
29+
MethodDefinition delegateMethod = TestObjectHelper.GetTestNFAppOneClassOverAllMethodDefinition(testDelegatesClassTypeDefinition, "SimpleDelegate");
30+
31+
uint flags = nanoMethodDefinitionTable.GetFlags(delegateMethod);
32+
33+
const uint expectedFlag = 0x00020000; // MD_DelegateInvoke
34+
Assert.AreEqual(expectedFlag, flags);
35+
36+
// Assert
37+
//const uint expectedFlag = 0x00000001; // MD_Scope_Private
38+
//Assert.AreEqual(expectedFlag, flags);
39+
}
40+
41+
[TestMethod]
42+
public void GetFlags_PublicStaticMethod_ReturnsPublicAndStaticFlags()
43+
{
44+
// Arrange
45+
var method = new MethodDefinition("TestMethod", MethodAttributes.Public | MethodAttributes.Static, null);
46+
47+
// Act
48+
uint flags = nanoMethodDefinitionTable.GetFlags(method);
49+
50+
// Assert
51+
const uint expectedFlags = 0x00000006 | 0x00000010; // MD_Scope_Public | MD_Static
52+
Assert.AreEqual(expectedFlags, flags);
53+
}
54+
55+
[TestMethod]
56+
public void GetFlags_AbstractVirtualMethod_ReturnsAbstractAndVirtualFlags()
57+
{
58+
// Arrange
59+
var method = new MethodDefinition("TestMethod", MethodAttributes.Abstract | MethodAttributes.Virtual, null);
60+
61+
// Act
62+
uint flags = nanoMethodDefinitionTable.GetFlags(method);
63+
64+
// Assert
65+
const uint expectedFlags = 0x00000200 | 0x00000040; // MD_Abstract | MD_Virtual
66+
Assert.AreEqual(expectedFlags, flags);
67+
}
68+
69+
#region delegate method flags
70+
71+
[TestMethod]
72+
public void TestDelegateInvokeMethodReturnsDelegateInvokeFlag()
73+
{
74+
var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", "Invoke");
75+
76+
uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition);
77+
78+
// Assert
79+
const uint expectedFlag = 0x00020000; // MD_DelegateInvoke
80+
Assert.AreEqual(expectedFlag, flags & expectedFlag);
81+
}
82+
83+
[TestMethod]
84+
public void TestDelegateConstructorMethodReturnsDelegateConstructorFlag()
85+
{
86+
var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", ".ctor");
87+
88+
uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition);
89+
90+
// Assert
91+
const uint expectedFlag = 0x00010000; // MD_DelegateConstructor
92+
Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for Delegate constructor.");
93+
}
94+
95+
[TestMethod]
96+
public void TestDelegateBeginInvokeMethodReturnsDelegateBeginInvokeFlag()
97+
{
98+
// Arrange
99+
var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", "BeginInvoke");
100+
101+
// Act
102+
uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition);
103+
104+
// Assert
105+
const uint expectedFlag = 0x00040000; // MD_DelegateBeginInvoke
106+
Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for BeginInvoke method.");
107+
}
108+
109+
[TestMethod]
110+
public void TestDelegateEndInvokeMethodReturnsDelegateEndInvokeFlag()
111+
{
112+
// Arrange
113+
var methodDefinition = TestObjectHelper.GetMethodDefinition(_testDelegatesClassTypeDefinition, "SimpleDelegate", "EndInvoke");
114+
115+
// Act
116+
uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition);
117+
118+
// Assert
119+
const uint expectedFlag = 0x00080000; // MD_DelegateEndInvoke
120+
Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for EndInvoke method.");
121+
}
122+
123+
#endregion
124+
}
125+
}

MetadataProcessor.Tests/MetadataProcessor.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
<Compile Include="Core\Mono.Cecil\CodeWriterTests.cs" />
6161
<Compile Include="Core\Tables\nanoAssemblyReferenceTableTests.cs" />
6262
<Compile Include="Core\Tables\nanoAttributesTableTests.cs" />
63+
<Compile Include="Core\Tables\nanoMethodDefinitionTableTests.cs" />
6364
<Compile Include="Core\Tables\nanoReferenceTableBaseTests.cs" />
6465
<Compile Include="Core\ClrIntegrationTests.cs" />
6566
<Compile Include="Core\Utility\DumperTests.cs" />

MetadataProcessor.Tests/TestNFApp/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public static void Main()
3737
// Reflection Tests
3838
ReflectionTests();
3939

40+
///////////////////////////////////////
41+
// Delegate and MulticastDelegate tests
42+
_ = new TestingDelegates();
43+
4044
////////////////////////////////////////////////
4145
// Test enum in another assembly, same namespace
4246
var enumTest = new TestEnumInAnotherAssembly();

MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<Compile Include="OneClassOverAll.cs" />
3333
<Compile Include="Program.cs" />
3434
<Compile Include="Properties\AssemblyInfo.cs" />
35+
<Compile Include="TestingDelegates.cs" />
3536
</ItemGroup>
3637
<ItemGroup>
3738
<ProjectReference Include="..\mscorlib\nanoFramework.CoreLibrary\CoreLibrary.nfproj" />
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
8+
namespace TestNFApp
9+
{
10+
public class TestingDelegates
11+
{
12+
public TestingDelegates()
13+
{
14+
DelegateTests();
15+
MulticastDelegateTests();
16+
}
17+
18+
// Define a delegate
19+
public delegate void SimpleDelegate(string message);
20+
21+
// Method that matches the delegate signature
22+
public void DisplayMessage(string message)
23+
{
24+
Console.WriteLine(message);
25+
}
26+
27+
// Another method that matches the delegate signature
28+
public void DisplayUpperCaseMessage(string message)
29+
{
30+
Console.WriteLine("Uppercase: " + message.ToUpper());
31+
}
32+
33+
// Another method that matches the delegate signature
34+
public void DisplayLowerCaseMessage(string message)
35+
{
36+
Console.WriteLine("Lowercase: " + message.ToLower());
37+
}
38+
39+
private void DelegateTests()
40+
{
41+
// Instantiate the delegate
42+
SimpleDelegate del = new SimpleDelegate(DisplayMessage);
43+
44+
// Call the delegate
45+
del("Hello, this is a delegate example!");
46+
47+
// Using delegate with anonymous method
48+
SimpleDelegate del2 = delegate (string msg)
49+
{
50+
Console.WriteLine(msg);
51+
};
52+
53+
del2("Hello, this is a delegate example called from an anonymous method!");
54+
55+
// Using delegate with lambda expression
56+
SimpleDelegate del3 = (msg) => Console.WriteLine(msg);
57+
58+
del3("Hello, this is a delegate example called from a lambda expression!");
59+
}
60+
61+
private void MulticastDelegateTests()
62+
{
63+
// Instantiate the delegate with multiple methods
64+
SimpleDelegate del = DisplayMessage;
65+
del += DisplayUpperCaseMessage;
66+
del += DisplayLowerCaseMessage;
67+
68+
// Call the multicast delegate
69+
del("Hello, this is a multicast delegate example!");
70+
}
71+
}
72+
}

MetadataProcessor.Tests/TestObjectHelper.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,5 +375,23 @@ public static void AdjustMethodBodyOffsets(Mono.Cecil.Cil.MethodBody methodBody)
375375
}
376376
}
377377

378+
internal static TypeDefinition GetTestNFAppTestingDelegatesTypeDefinition(AssemblyDefinition assemblyDefinition)
379+
{
380+
TypeDefinition ret = null;
381+
382+
var module = assemblyDefinition.Modules[0];
383+
ret = module.Types.First(i => i.FullName == "TestNFApp.TestingDelegates");
384+
385+
return ret;
386+
}
387+
388+
internal static MethodDefinition GetMethodDefinition(
389+
TypeDefinition typeDefinition,
390+
string delegateName,
391+
string methodName)
392+
{
393+
var delegateType = typeDefinition.NestedTypes.First(nt => nt.Name == delegateName);
394+
return delegateType.Methods.First(m => m.Name == methodName);
395+
}
378396
}
379397
}

0 commit comments

Comments
 (0)