com.wallstop-studios.unity-helpers 2.0.0-rc79.4 → 2.0.0-rc79.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/npm-publish.yml +2 -2
- package/Runtime/Core/Extension/EnumExtensions.cs +1 -1
- package/Runtime/Core/Extension/IReadonlyListExtensions.cs +1 -1
- package/Runtime/Core/Extension/IReadonlyListExtensions.cs.meta +1 -1
- package/Runtime/Core/Extension/StringExtensions.cs +1 -1
- package/Runtime/Core/Helper/ReflectionHelpers.cs +1368 -22
- package/Runtime/Core/Helper/StringInList.cs +3 -21
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +157 -49
- package/Runtime/Utils/Buffers.cs +2 -2
- package/Runtime/Utils/SevenZip/Common/CRC.cs +9 -0
- package/Runtime/Utils/SevenZip/Common/InBuffer.cs +15 -2
- package/Runtime/Utils/SevenZip/Common/OutBuffer.cs +7 -2
- package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs +50 -0
- package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs +26 -0
- package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs +27 -0
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs +9 -0
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs +80 -17
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs +265 -30
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs +9 -0
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +13 -1
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +11 -4
- package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs +54 -0
- package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs.meta +3 -0
- package/Tests/Runtime/Core/Threading.meta +3 -0
- package/Tests/Runtime/Core.meta +3 -0
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +1 -1
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs.meta +1 -1
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/StringExtensionTests.cs +1 -1
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -1
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs +961 -0
- package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +1 -2
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +1 -1
- package/Tests/Runtime/Utils/BuffersTests.cs +6 -6
- package/Tests/Runtime/Utils/BuffersTests.cs.meta +1 -1
- package/package.json +3 -1
|
@@ -3,10 +3,28 @@ namespace WallstopStudios.UnityHelpers.Tests.Helper
|
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections;
|
|
5
5
|
using System.Collections.Generic;
|
|
6
|
+
using System.Linq;
|
|
6
7
|
using System.Reflection;
|
|
7
8
|
using NUnit.Framework;
|
|
8
9
|
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
9
10
|
using WallstopStudios.UnityHelpers.Core.Random;
|
|
11
|
+
using CategoryAttribute = System.ComponentModel.CategoryAttribute;
|
|
12
|
+
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
|
|
13
|
+
|
|
14
|
+
[AttributeUsage(AttributeTargets.All)]
|
|
15
|
+
public class ReflectionTestAttribute : Attribute
|
|
16
|
+
{
|
|
17
|
+
public string Name { get; set; }
|
|
18
|
+
public int Value { get; set; }
|
|
19
|
+
|
|
20
|
+
public ReflectionTestAttribute() { }
|
|
21
|
+
|
|
22
|
+
public ReflectionTestAttribute(string name, int value)
|
|
23
|
+
{
|
|
24
|
+
Name = name;
|
|
25
|
+
Value = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
10
28
|
|
|
11
29
|
public struct TestStruct
|
|
12
30
|
{
|
|
@@ -20,6 +38,202 @@ namespace WallstopStudios.UnityHelpers.Tests.Helper
|
|
|
20
38
|
public int intValue;
|
|
21
39
|
}
|
|
22
40
|
|
|
41
|
+
public class TestMethodClass
|
|
42
|
+
{
|
|
43
|
+
public static int StaticMethodCallCount = 0;
|
|
44
|
+
public int InstanceMethodCallCount = 0;
|
|
45
|
+
|
|
46
|
+
// Void methods
|
|
47
|
+
public static void StaticVoidMethod()
|
|
48
|
+
{
|
|
49
|
+
StaticMethodCallCount++;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public void InstanceVoidMethod()
|
|
53
|
+
{
|
|
54
|
+
InstanceMethodCallCount++;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Return value methods
|
|
58
|
+
public static int StaticIntMethod()
|
|
59
|
+
{
|
|
60
|
+
StaticMethodCallCount++;
|
|
61
|
+
return 42;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static string StaticStringMethod()
|
|
65
|
+
{
|
|
66
|
+
StaticMethodCallCount++;
|
|
67
|
+
return "test";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public static bool StaticBoolMethod()
|
|
71
|
+
{
|
|
72
|
+
StaticMethodCallCount++;
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public int InstanceIntMethod()
|
|
77
|
+
{
|
|
78
|
+
InstanceMethodCallCount++;
|
|
79
|
+
return 100;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public string InstanceStringMethod()
|
|
83
|
+
{
|
|
84
|
+
InstanceMethodCallCount++;
|
|
85
|
+
return "instance";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Methods with parameters
|
|
89
|
+
public static int StaticMethodWithParam(int param)
|
|
90
|
+
{
|
|
91
|
+
StaticMethodCallCount++;
|
|
92
|
+
return param * 2;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public int InstanceMethodWithParam(string param)
|
|
96
|
+
{
|
|
97
|
+
InstanceMethodCallCount++;
|
|
98
|
+
return param?.Length ?? 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public static void StaticVoidMethodWithParam(int param)
|
|
102
|
+
{
|
|
103
|
+
StaticMethodCallCount = param;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Multiple parameter methods
|
|
107
|
+
public static int StaticMethodMultipleParams(int a, string b, bool c)
|
|
108
|
+
{
|
|
109
|
+
StaticMethodCallCount++;
|
|
110
|
+
return a + (b?.Length ?? 0) + (c ? 1 : 0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public void Reset()
|
|
114
|
+
{
|
|
115
|
+
StaticMethodCallCount = 0;
|
|
116
|
+
InstanceMethodCallCount = 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public sealed class TestConstructorClass
|
|
121
|
+
{
|
|
122
|
+
public int Value1 { get; }
|
|
123
|
+
public string Value2 { get; }
|
|
124
|
+
public bool Value3 { get; }
|
|
125
|
+
|
|
126
|
+
public TestConstructorClass()
|
|
127
|
+
{
|
|
128
|
+
Value1 = 0;
|
|
129
|
+
Value2 = "default";
|
|
130
|
+
Value3 = false;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public TestConstructorClass(int value1)
|
|
134
|
+
{
|
|
135
|
+
Value1 = value1;
|
|
136
|
+
Value2 = "single";
|
|
137
|
+
Value3 = false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public TestConstructorClass(int value1, string value2)
|
|
141
|
+
{
|
|
142
|
+
Value1 = value1;
|
|
143
|
+
Value2 = value2;
|
|
144
|
+
Value3 = false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public TestConstructorClass(int value1, string value2, bool value3)
|
|
148
|
+
{
|
|
149
|
+
Value1 = value1;
|
|
150
|
+
Value2 = value2;
|
|
151
|
+
Value3 = value3;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public readonly struct TestConstructorStruct
|
|
156
|
+
{
|
|
157
|
+
public int Value { get; }
|
|
158
|
+
|
|
159
|
+
public TestConstructorStruct(int value)
|
|
160
|
+
{
|
|
161
|
+
Value = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public sealed class TestPropertyClass
|
|
166
|
+
{
|
|
167
|
+
private static int _staticValue = 50;
|
|
168
|
+
private int _instanceValue = 25;
|
|
169
|
+
|
|
170
|
+
public static int StaticProperty
|
|
171
|
+
{
|
|
172
|
+
get => _staticValue;
|
|
173
|
+
set => _staticValue = value;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public int InstanceProperty
|
|
177
|
+
{
|
|
178
|
+
get => _instanceValue;
|
|
179
|
+
set => _instanceValue = value;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public static string StaticStringProperty { get; set; } = "static";
|
|
183
|
+
|
|
184
|
+
public string InstanceStringProperty { get; set; } = "instance";
|
|
185
|
+
|
|
186
|
+
// Read-only properties
|
|
187
|
+
public static int StaticReadOnlyProperty => 999;
|
|
188
|
+
public int InstanceReadOnlyProperty => 888;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
[Description("Test class for attribute testing")]
|
|
192
|
+
[ReflectionTestAttribute("ClassLevel", 10)]
|
|
193
|
+
public sealed class TestAttributeClass
|
|
194
|
+
{
|
|
195
|
+
[Description("Static field with description")]
|
|
196
|
+
[ReflectionTestAttribute("StaticField", 15)]
|
|
197
|
+
public static int StaticFieldWithAttribute = 1;
|
|
198
|
+
|
|
199
|
+
[Category("TestCategory")]
|
|
200
|
+
[ReflectionTestAttribute("InstanceField", 5)]
|
|
201
|
+
public int InstanceFieldWithAttribute = 2;
|
|
202
|
+
|
|
203
|
+
[Description("Static property for testing")]
|
|
204
|
+
[ReflectionTestAttribute("StaticProperty", 20)]
|
|
205
|
+
public static string StaticPropertyWithAttribute { get; set; } = "static";
|
|
206
|
+
|
|
207
|
+
[Category("TestCategory")]
|
|
208
|
+
[Description("Instance property")]
|
|
209
|
+
[ReflectionTestAttribute("InstanceProperty", 8)]
|
|
210
|
+
public string InstancePropertyWithAttribute { get; set; } = "instance";
|
|
211
|
+
|
|
212
|
+
[Description("Static method for testing")]
|
|
213
|
+
[ReflectionTestAttribute("StaticMethod", 12)]
|
|
214
|
+
public static void StaticMethodWithAttribute() { }
|
|
215
|
+
|
|
216
|
+
[Category("TestCategory")]
|
|
217
|
+
[ReflectionTestAttribute("InstanceMethod", 7)]
|
|
218
|
+
public void InstanceMethodWithAttribute() { }
|
|
219
|
+
|
|
220
|
+
public void MethodWithAttributedParameter(
|
|
221
|
+
[Description("Parameter with description")] int param
|
|
222
|
+
) { }
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
public sealed class GenericTestClass<T>
|
|
226
|
+
{
|
|
227
|
+
public T Value { get; set; }
|
|
228
|
+
|
|
229
|
+
public GenericTestClass() { }
|
|
230
|
+
|
|
231
|
+
public GenericTestClass(T value)
|
|
232
|
+
{
|
|
233
|
+
Value = value;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
23
237
|
public sealed class ReflectionHelperTests
|
|
24
238
|
{
|
|
25
239
|
private const int NumTries = 1_000;
|
|
@@ -528,5 +742,752 @@ namespace WallstopStudios.UnityHelpers.Tests.Helper
|
|
|
528
742
|
}
|
|
529
743
|
}
|
|
530
744
|
}
|
|
745
|
+
|
|
746
|
+
[Test]
|
|
747
|
+
public void GetArrayCreator()
|
|
748
|
+
{
|
|
749
|
+
Func<int, Array> arrayCreator = ReflectionHelpers.GetArrayCreator(typeof(int));
|
|
750
|
+
Assert.IsNotNull(arrayCreator);
|
|
751
|
+
|
|
752
|
+
for (int i = 0; i < 10; ++i)
|
|
753
|
+
{
|
|
754
|
+
int size = PRNG.Instance.Next(1, 100);
|
|
755
|
+
Array created = arrayCreator(size);
|
|
756
|
+
Assert.IsNotNull(created);
|
|
757
|
+
Assert.AreEqual(size, created.Length);
|
|
758
|
+
Assert.IsTrue(created is int[]);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
[Test]
|
|
763
|
+
public void GetListCreator()
|
|
764
|
+
{
|
|
765
|
+
Func<IList> listCreator = ReflectionHelpers.GetListCreator(typeof(string));
|
|
766
|
+
Assert.IsNotNull(listCreator);
|
|
767
|
+
|
|
768
|
+
for (int i = 0; i < 10; ++i)
|
|
769
|
+
{
|
|
770
|
+
IList created = listCreator();
|
|
771
|
+
Assert.IsNotNull(created);
|
|
772
|
+
Assert.AreEqual(0, created.Count);
|
|
773
|
+
Assert.IsTrue(created is List<string>);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
[Test]
|
|
778
|
+
public void GetListWithCapacityCreator()
|
|
779
|
+
{
|
|
780
|
+
Func<int, IList> listCreator = ReflectionHelpers.GetListWithCapacityCreator(
|
|
781
|
+
typeof(bool)
|
|
782
|
+
);
|
|
783
|
+
Assert.IsNotNull(listCreator);
|
|
784
|
+
|
|
785
|
+
for (int i = 0; i < 10; ++i)
|
|
786
|
+
{
|
|
787
|
+
int capacity = PRNG.Instance.Next(1, 100);
|
|
788
|
+
IList created = listCreator(capacity);
|
|
789
|
+
Assert.IsNotNull(created);
|
|
790
|
+
Assert.AreEqual(0, created.Count);
|
|
791
|
+
Assert.IsTrue(created is List<bool>);
|
|
792
|
+
Assert.AreEqual(capacity, ((List<bool>)created).Capacity);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
[Test]
|
|
797
|
+
public void InvokeStaticVoidMethod()
|
|
798
|
+
{
|
|
799
|
+
TestMethodClass testObj = new();
|
|
800
|
+
testObj.Reset();
|
|
801
|
+
|
|
802
|
+
MethodInfo method = typeof(TestMethodClass).GetMethod(
|
|
803
|
+
nameof(TestMethodClass.StaticVoidMethod)
|
|
804
|
+
);
|
|
805
|
+
Assert.IsNotNull(method);
|
|
806
|
+
|
|
807
|
+
int initialCount = TestMethodClass.StaticMethodCallCount;
|
|
808
|
+
object result = ReflectionHelpers.InvokeStaticMethod(method);
|
|
809
|
+
|
|
810
|
+
Assert.IsNull(result);
|
|
811
|
+
Assert.AreEqual(initialCount + 1, TestMethodClass.StaticMethodCallCount);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
[Test]
|
|
815
|
+
public void InvokeStaticMethodWithReturnValue()
|
|
816
|
+
{
|
|
817
|
+
TestMethodClass testObj = new();
|
|
818
|
+
testObj.Reset();
|
|
819
|
+
|
|
820
|
+
MethodInfo intMethod = typeof(TestMethodClass).GetMethod(
|
|
821
|
+
nameof(TestMethodClass.StaticIntMethod)
|
|
822
|
+
);
|
|
823
|
+
MethodInfo stringMethod = typeof(TestMethodClass).GetMethod(
|
|
824
|
+
nameof(TestMethodClass.StaticStringMethod)
|
|
825
|
+
);
|
|
826
|
+
MethodInfo boolMethod = typeof(TestMethodClass).GetMethod(
|
|
827
|
+
nameof(TestMethodClass.StaticBoolMethod)
|
|
828
|
+
);
|
|
829
|
+
|
|
830
|
+
Assert.AreEqual(42, ReflectionHelpers.InvokeStaticMethod(intMethod));
|
|
831
|
+
Assert.AreEqual("test", ReflectionHelpers.InvokeStaticMethod(stringMethod));
|
|
832
|
+
Assert.AreEqual(true, ReflectionHelpers.InvokeStaticMethod(boolMethod));
|
|
833
|
+
Assert.AreEqual(3, TestMethodClass.StaticMethodCallCount);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
[Test]
|
|
837
|
+
public void InvokeStaticMethodWithParameters()
|
|
838
|
+
{
|
|
839
|
+
var directResult = TestMethodClass.StaticMethodWithParam(10);
|
|
840
|
+
Assert.AreEqual(20, directResult);
|
|
841
|
+
|
|
842
|
+
TestMethodClass testObj = new();
|
|
843
|
+
testObj.Reset();
|
|
844
|
+
|
|
845
|
+
MethodInfo paramMethod = typeof(TestMethodClass).GetMethod(
|
|
846
|
+
nameof(TestMethodClass.StaticMethodWithParam)
|
|
847
|
+
);
|
|
848
|
+
MethodInfo voidParamMethod = typeof(TestMethodClass).GetMethod(
|
|
849
|
+
nameof(TestMethodClass.StaticVoidMethodWithParam)
|
|
850
|
+
);
|
|
851
|
+
MethodInfo multiParamMethod = typeof(TestMethodClass).GetMethod(
|
|
852
|
+
nameof(TestMethodClass.StaticMethodMultipleParams)
|
|
853
|
+
);
|
|
854
|
+
|
|
855
|
+
var result1 = ReflectionHelpers.InvokeStaticMethod(paramMethod, 10);
|
|
856
|
+
Assert.AreEqual(20, result1);
|
|
857
|
+
ReflectionHelpers.InvokeStaticMethod(voidParamMethod, 99);
|
|
858
|
+
Assert.AreEqual(99, TestMethodClass.StaticMethodCallCount);
|
|
859
|
+
var result3 = ReflectionHelpers.InvokeStaticMethod(multiParamMethod, 5, "abc", true);
|
|
860
|
+
Assert.AreEqual(9, result3);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
[Test]
|
|
864
|
+
public void InvokeInstanceMethod()
|
|
865
|
+
{
|
|
866
|
+
TestMethodClass testObj = new();
|
|
867
|
+
testObj.Reset();
|
|
868
|
+
|
|
869
|
+
MethodInfo voidMethod = typeof(TestMethodClass).GetMethod(
|
|
870
|
+
nameof(TestMethodClass.InstanceVoidMethod)
|
|
871
|
+
);
|
|
872
|
+
MethodInfo intMethod = typeof(TestMethodClass).GetMethod(
|
|
873
|
+
nameof(TestMethodClass.InstanceIntMethod)
|
|
874
|
+
);
|
|
875
|
+
MethodInfo stringMethod = typeof(TestMethodClass).GetMethod(
|
|
876
|
+
nameof(TestMethodClass.InstanceStringMethod)
|
|
877
|
+
);
|
|
878
|
+
MethodInfo paramMethod = typeof(TestMethodClass).GetMethod(
|
|
879
|
+
nameof(TestMethodClass.InstanceMethodWithParam)
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
Assert.IsNull(ReflectionHelpers.InvokeMethod(voidMethod, testObj));
|
|
883
|
+
Assert.AreEqual(1, testObj.InstanceMethodCallCount);
|
|
884
|
+
|
|
885
|
+
Assert.AreEqual(100, ReflectionHelpers.InvokeMethod(intMethod, testObj));
|
|
886
|
+
Assert.AreEqual("instance", ReflectionHelpers.InvokeMethod(stringMethod, testObj));
|
|
887
|
+
Assert.AreEqual(5, ReflectionHelpers.InvokeMethod(paramMethod, testObj, "hello"));
|
|
888
|
+
Assert.AreEqual(4, testObj.InstanceMethodCallCount);
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
[Test]
|
|
892
|
+
public void GetMethodInvoker()
|
|
893
|
+
{
|
|
894
|
+
TestMethodClass testObj = new();
|
|
895
|
+
testObj.Reset();
|
|
896
|
+
|
|
897
|
+
MethodInfo voidMethod = typeof(TestMethodClass).GetMethod(
|
|
898
|
+
nameof(TestMethodClass.InstanceVoidMethod)
|
|
899
|
+
);
|
|
900
|
+
MethodInfo intMethod = typeof(TestMethodClass).GetMethod(
|
|
901
|
+
nameof(TestMethodClass.InstanceIntMethod)
|
|
902
|
+
);
|
|
903
|
+
MethodInfo paramMethod = typeof(TestMethodClass).GetMethod(
|
|
904
|
+
nameof(TestMethodClass.InstanceMethodWithParam)
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
Func<object, object[], object> voidInvoker = ReflectionHelpers.GetMethodInvoker(
|
|
908
|
+
voidMethod
|
|
909
|
+
);
|
|
910
|
+
Func<object, object[], object> intInvoker = ReflectionHelpers.GetMethodInvoker(
|
|
911
|
+
intMethod
|
|
912
|
+
);
|
|
913
|
+
Func<object, object[], object> paramInvoker = ReflectionHelpers.GetMethodInvoker(
|
|
914
|
+
paramMethod
|
|
915
|
+
);
|
|
916
|
+
|
|
917
|
+
Assert.IsNull(voidInvoker(testObj, Array.Empty<object>()));
|
|
918
|
+
Assert.AreEqual(1, testObj.InstanceMethodCallCount);
|
|
919
|
+
|
|
920
|
+
Assert.AreEqual(100, intInvoker(testObj, Array.Empty<object>()));
|
|
921
|
+
Assert.AreEqual(2, testObj.InstanceMethodCallCount);
|
|
922
|
+
|
|
923
|
+
Assert.AreEqual(5, paramInvoker(testObj, new object[] { "hello" }));
|
|
924
|
+
Assert.AreEqual(3, testObj.InstanceMethodCallCount);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
[Test]
|
|
928
|
+
public void GetStaticMethodInvoker()
|
|
929
|
+
{
|
|
930
|
+
TestMethodClass testObj = new();
|
|
931
|
+
testObj.Reset();
|
|
932
|
+
|
|
933
|
+
MethodInfo voidMethod = typeof(TestMethodClass).GetMethod(
|
|
934
|
+
nameof(TestMethodClass.StaticVoidMethod)
|
|
935
|
+
);
|
|
936
|
+
MethodInfo intMethod = typeof(TestMethodClass).GetMethod(
|
|
937
|
+
nameof(TestMethodClass.StaticIntMethod)
|
|
938
|
+
);
|
|
939
|
+
MethodInfo paramMethod = typeof(TestMethodClass).GetMethod(
|
|
940
|
+
nameof(TestMethodClass.StaticMethodWithParam)
|
|
941
|
+
);
|
|
942
|
+
|
|
943
|
+
Func<object[], object> voidInvoker = ReflectionHelpers.GetStaticMethodInvoker(
|
|
944
|
+
voidMethod
|
|
945
|
+
);
|
|
946
|
+
Func<object[], object> intInvoker = ReflectionHelpers.GetStaticMethodInvoker(intMethod);
|
|
947
|
+
Func<object[], object> paramInvoker = ReflectionHelpers.GetStaticMethodInvoker(
|
|
948
|
+
paramMethod
|
|
949
|
+
);
|
|
950
|
+
|
|
951
|
+
Assert.IsNull(voidInvoker(Array.Empty<object>()));
|
|
952
|
+
Assert.AreEqual(1, TestMethodClass.StaticMethodCallCount);
|
|
953
|
+
|
|
954
|
+
Assert.AreEqual(42, intInvoker(Array.Empty<object>()));
|
|
955
|
+
Assert.AreEqual(2, TestMethodClass.StaticMethodCallCount);
|
|
956
|
+
|
|
957
|
+
Assert.AreEqual(20, paramInvoker(new object[] { 10 }));
|
|
958
|
+
Assert.AreEqual(3, TestMethodClass.StaticMethodCallCount);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
[Test]
|
|
962
|
+
public void CreateInstanceParameterless()
|
|
963
|
+
{
|
|
964
|
+
TestConstructorClass defaultInstance =
|
|
965
|
+
ReflectionHelpers.CreateInstance<TestConstructorClass>();
|
|
966
|
+
Assert.IsNotNull(defaultInstance);
|
|
967
|
+
Assert.AreEqual(0, defaultInstance.Value1);
|
|
968
|
+
Assert.AreEqual("default", defaultInstance.Value2);
|
|
969
|
+
Assert.AreEqual(false, defaultInstance.Value3);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
[Test]
|
|
973
|
+
public void CreateInstanceWithParameters()
|
|
974
|
+
{
|
|
975
|
+
TestConstructorClass singleParam =
|
|
976
|
+
ReflectionHelpers.CreateInstance<TestConstructorClass>(42);
|
|
977
|
+
Assert.IsNotNull(singleParam);
|
|
978
|
+
Assert.AreEqual(42, singleParam.Value1);
|
|
979
|
+
Assert.AreEqual("single", singleParam.Value2);
|
|
980
|
+
Assert.AreEqual(false, singleParam.Value3);
|
|
981
|
+
|
|
982
|
+
TestConstructorClass twoParam = ReflectionHelpers.CreateInstance<TestConstructorClass>(
|
|
983
|
+
10,
|
|
984
|
+
"test"
|
|
985
|
+
);
|
|
986
|
+
Assert.IsNotNull(twoParam);
|
|
987
|
+
Assert.AreEqual(10, twoParam.Value1);
|
|
988
|
+
Assert.AreEqual("test", twoParam.Value2);
|
|
989
|
+
Assert.AreEqual(false, twoParam.Value3);
|
|
990
|
+
|
|
991
|
+
TestConstructorClass threeParam =
|
|
992
|
+
ReflectionHelpers.CreateInstance<TestConstructorClass>(5, "hello", true);
|
|
993
|
+
Assert.IsNotNull(threeParam);
|
|
994
|
+
Assert.AreEqual(5, threeParam.Value1);
|
|
995
|
+
Assert.AreEqual("hello", threeParam.Value2);
|
|
996
|
+
Assert.AreEqual(true, threeParam.Value3);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
[Test]
|
|
1000
|
+
public void CreateInstanceUsingConstructorInfo()
|
|
1001
|
+
{
|
|
1002
|
+
ConstructorInfo[] constructors = typeof(TestConstructorClass).GetConstructors();
|
|
1003
|
+
ConstructorInfo parameterlessConstructor = constructors.First(c =>
|
|
1004
|
+
c.GetParameters().Length == 0
|
|
1005
|
+
);
|
|
1006
|
+
ConstructorInfo singleParamConstructor = constructors.First(c =>
|
|
1007
|
+
c.GetParameters().Length == 1
|
|
1008
|
+
);
|
|
1009
|
+
|
|
1010
|
+
Func<object[], object> parameterlessDelegate = ReflectionHelpers.GetConstructor(
|
|
1011
|
+
parameterlessConstructor
|
|
1012
|
+
);
|
|
1013
|
+
Func<object[], object> singleParamDelegate = ReflectionHelpers.GetConstructor(
|
|
1014
|
+
singleParamConstructor
|
|
1015
|
+
);
|
|
1016
|
+
|
|
1017
|
+
TestConstructorClass instance1 = (TestConstructorClass)parameterlessDelegate(
|
|
1018
|
+
Array.Empty<object>()
|
|
1019
|
+
);
|
|
1020
|
+
Assert.AreEqual(0, instance1.Value1);
|
|
1021
|
+
Assert.AreEqual("default", instance1.Value2);
|
|
1022
|
+
|
|
1023
|
+
TestConstructorClass instance2 = (TestConstructorClass)singleParamDelegate(
|
|
1024
|
+
new object[] { 99 }
|
|
1025
|
+
);
|
|
1026
|
+
Assert.AreEqual(99, instance2.Value1);
|
|
1027
|
+
Assert.AreEqual("single", instance2.Value2);
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
[Test]
|
|
1031
|
+
public void GetParameterlessConstructor()
|
|
1032
|
+
{
|
|
1033
|
+
Func<TestConstructorClass> constructor =
|
|
1034
|
+
ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
|
|
1035
|
+
Assert.IsNotNull(constructor);
|
|
1036
|
+
|
|
1037
|
+
for (int i = 0; i < 100; i++)
|
|
1038
|
+
{
|
|
1039
|
+
TestConstructorClass instance = constructor();
|
|
1040
|
+
Assert.IsNotNull(instance);
|
|
1041
|
+
Assert.AreEqual(0, instance.Value1);
|
|
1042
|
+
Assert.AreEqual("default", instance.Value2);
|
|
1043
|
+
Assert.AreEqual(false, instance.Value3);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
[Test]
|
|
1048
|
+
public void CreateGenericInstance()
|
|
1049
|
+
{
|
|
1050
|
+
object intGeneric = ReflectionHelpers.CreateGenericInstance<object>(
|
|
1051
|
+
typeof(GenericTestClass<>),
|
|
1052
|
+
new[] { typeof(int) },
|
|
1053
|
+
42
|
|
1054
|
+
);
|
|
1055
|
+
|
|
1056
|
+
Assert.IsNotNull(intGeneric);
|
|
1057
|
+
Assert.IsInstanceOf<GenericTestClass<int>>(intGeneric);
|
|
1058
|
+
Assert.AreEqual(42, ((GenericTestClass<int>)intGeneric).Value);
|
|
1059
|
+
|
|
1060
|
+
object stringGeneric = ReflectionHelpers.CreateGenericInstance<object>(
|
|
1061
|
+
typeof(GenericTestClass<>),
|
|
1062
|
+
new[] { typeof(string) },
|
|
1063
|
+
"hello"
|
|
1064
|
+
);
|
|
1065
|
+
|
|
1066
|
+
Assert.IsNotNull(stringGeneric);
|
|
1067
|
+
Assert.IsInstanceOf<GenericTestClass<string>>(stringGeneric);
|
|
1068
|
+
Assert.AreEqual("hello", ((GenericTestClass<string>)stringGeneric).Value);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
[Test]
|
|
1072
|
+
public void GetGenericParameterlessConstructor()
|
|
1073
|
+
{
|
|
1074
|
+
Func<object> constructor = ReflectionHelpers.GetGenericParameterlessConstructor<object>(
|
|
1075
|
+
typeof(GenericTestClass<>),
|
|
1076
|
+
typeof(int)
|
|
1077
|
+
);
|
|
1078
|
+
|
|
1079
|
+
Assert.IsNotNull(constructor);
|
|
1080
|
+
|
|
1081
|
+
object instance = constructor();
|
|
1082
|
+
Assert.IsNotNull(instance);
|
|
1083
|
+
Assert.IsInstanceOf<GenericTestClass<int>>(instance);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
[Test]
|
|
1087
|
+
public void CreateStructInstance()
|
|
1088
|
+
{
|
|
1089
|
+
TestConstructorStruct structInstance =
|
|
1090
|
+
ReflectionHelpers.CreateInstance<TestConstructorStruct>(123);
|
|
1091
|
+
Assert.AreEqual(123, structInstance.Value);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
[Test]
|
|
1095
|
+
public void GetPropertyGetterStatic()
|
|
1096
|
+
{
|
|
1097
|
+
PropertyInfo staticProp = typeof(TestPropertyClass).GetProperty(
|
|
1098
|
+
nameof(TestPropertyClass.StaticProperty)
|
|
1099
|
+
);
|
|
1100
|
+
PropertyInfo staticStringProp = typeof(TestPropertyClass).GetProperty(
|
|
1101
|
+
nameof(TestPropertyClass.StaticStringProperty)
|
|
1102
|
+
);
|
|
1103
|
+
PropertyInfo staticReadOnlyProp = typeof(TestPropertyClass).GetProperty(
|
|
1104
|
+
nameof(TestPropertyClass.StaticReadOnlyProperty)
|
|
1105
|
+
);
|
|
1106
|
+
|
|
1107
|
+
Func<object, object> staticGetter = ReflectionHelpers.GetPropertyGetter(staticProp);
|
|
1108
|
+
Func<object, object> staticStringGetter = ReflectionHelpers.GetPropertyGetter(
|
|
1109
|
+
staticStringProp
|
|
1110
|
+
);
|
|
1111
|
+
Func<object, object> staticReadOnlyGetter = ReflectionHelpers.GetPropertyGetter(
|
|
1112
|
+
staticReadOnlyProp
|
|
1113
|
+
);
|
|
1114
|
+
|
|
1115
|
+
// Test initial values
|
|
1116
|
+
Assert.AreEqual(50, staticGetter(null));
|
|
1117
|
+
Assert.AreEqual("static", staticStringGetter(null));
|
|
1118
|
+
Assert.AreEqual(999, staticReadOnlyGetter(null));
|
|
1119
|
+
|
|
1120
|
+
// Test after changing values
|
|
1121
|
+
TestPropertyClass.StaticProperty = 100;
|
|
1122
|
+
TestPropertyClass.StaticStringProperty = "changed";
|
|
1123
|
+
|
|
1124
|
+
Assert.AreEqual(100, staticGetter(null));
|
|
1125
|
+
Assert.AreEqual("changed", staticStringGetter(null));
|
|
1126
|
+
Assert.AreEqual(999, staticReadOnlyGetter(null)); // Read-only shouldn't change
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
[Test]
|
|
1130
|
+
public void GetPropertyGetterInstance()
|
|
1131
|
+
{
|
|
1132
|
+
TestPropertyClass testObj = new();
|
|
1133
|
+
PropertyInfo instanceProp = typeof(TestPropertyClass).GetProperty(
|
|
1134
|
+
nameof(TestPropertyClass.InstanceProperty)
|
|
1135
|
+
);
|
|
1136
|
+
PropertyInfo instanceStringProp = typeof(TestPropertyClass).GetProperty(
|
|
1137
|
+
nameof(TestPropertyClass.InstanceStringProperty)
|
|
1138
|
+
);
|
|
1139
|
+
PropertyInfo instanceReadOnlyProp = typeof(TestPropertyClass).GetProperty(
|
|
1140
|
+
nameof(TestPropertyClass.InstanceReadOnlyProperty)
|
|
1141
|
+
);
|
|
1142
|
+
|
|
1143
|
+
Func<object, object> instanceGetter = ReflectionHelpers.GetPropertyGetter(instanceProp);
|
|
1144
|
+
Func<object, object> instanceStringGetter = ReflectionHelpers.GetPropertyGetter(
|
|
1145
|
+
instanceStringProp
|
|
1146
|
+
);
|
|
1147
|
+
Func<object, object> instanceReadOnlyGetter = ReflectionHelpers.GetPropertyGetter(
|
|
1148
|
+
instanceReadOnlyProp
|
|
1149
|
+
);
|
|
1150
|
+
|
|
1151
|
+
// Test initial values
|
|
1152
|
+
Assert.AreEqual(25, instanceGetter(testObj));
|
|
1153
|
+
Assert.AreEqual("instance", instanceStringGetter(testObj));
|
|
1154
|
+
Assert.AreEqual(888, instanceReadOnlyGetter(testObj));
|
|
1155
|
+
|
|
1156
|
+
// Test after changing values
|
|
1157
|
+
testObj.InstanceProperty = 200;
|
|
1158
|
+
testObj.InstanceStringProperty = "modified";
|
|
1159
|
+
|
|
1160
|
+
Assert.AreEqual(200, instanceGetter(testObj));
|
|
1161
|
+
Assert.AreEqual("modified", instanceStringGetter(testObj));
|
|
1162
|
+
Assert.AreEqual(888, instanceReadOnlyGetter(testObj)); // Read-only shouldn't change
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
[Test]
|
|
1166
|
+
public void GetStaticPropertyGetter()
|
|
1167
|
+
{
|
|
1168
|
+
Func<int> staticGetter = ReflectionHelpers.GetStaticPropertyGetter<int>(
|
|
1169
|
+
typeof(TestPropertyClass).GetProperty(nameof(TestPropertyClass.StaticProperty))
|
|
1170
|
+
);
|
|
1171
|
+
|
|
1172
|
+
Func<string> staticStringGetter = ReflectionHelpers.GetStaticPropertyGetter<string>(
|
|
1173
|
+
typeof(TestPropertyClass).GetProperty(
|
|
1174
|
+
nameof(TestPropertyClass.StaticStringProperty)
|
|
1175
|
+
)
|
|
1176
|
+
);
|
|
1177
|
+
|
|
1178
|
+
Assert.AreEqual(TestPropertyClass.StaticProperty, staticGetter());
|
|
1179
|
+
Assert.AreEqual(TestPropertyClass.StaticStringProperty, staticStringGetter());
|
|
1180
|
+
|
|
1181
|
+
TestPropertyClass.StaticProperty = 777;
|
|
1182
|
+
TestPropertyClass.StaticStringProperty = "new value";
|
|
1183
|
+
|
|
1184
|
+
Assert.AreEqual(777, staticGetter());
|
|
1185
|
+
Assert.AreEqual("new value", staticStringGetter());
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
[Test]
|
|
1189
|
+
public void GetAllLoadedAssemblies()
|
|
1190
|
+
{
|
|
1191
|
+
Assembly[] assemblies = ReflectionHelpers.GetAllLoadedAssemblies().ToArray();
|
|
1192
|
+
Assert.IsNotNull(assemblies);
|
|
1193
|
+
Assert.Greater(assemblies.Length, 0);
|
|
1194
|
+
Assert.IsTrue(assemblies.All(a => a != null));
|
|
1195
|
+
Assert.IsTrue(assemblies.All(a => !a.IsDynamic));
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
[Test]
|
|
1199
|
+
public void GetAllLoadedTypes()
|
|
1200
|
+
{
|
|
1201
|
+
Type[] types = ReflectionHelpers.GetAllLoadedTypes().Take(100).ToArray();
|
|
1202
|
+
Assert.IsNotNull(types);
|
|
1203
|
+
Assert.Greater(types.Length, 0);
|
|
1204
|
+
Assert.IsTrue(types.All(t => t != null));
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
[Test]
|
|
1208
|
+
public void GetTypesFromAssembly()
|
|
1209
|
+
{
|
|
1210
|
+
Assembly testAssembly = typeof(ReflectionHelperTests).Assembly;
|
|
1211
|
+
Type[] types = ReflectionHelpers.GetTypesFromAssembly(testAssembly).ToArray();
|
|
1212
|
+
|
|
1213
|
+
Assert.IsNotNull(types);
|
|
1214
|
+
Assert.Greater(types.Length, 0);
|
|
1215
|
+
Assert.IsTrue(types.Contains(typeof(ReflectionHelperTests)));
|
|
1216
|
+
Assert.IsTrue(types.Contains(typeof(TestAttributeClass)));
|
|
1217
|
+
Assert.IsTrue(types.Contains(typeof(TestMethodClass)));
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
[Test]
|
|
1221
|
+
public void GetTypesFromAssemblyName()
|
|
1222
|
+
{
|
|
1223
|
+
Type[] types = ReflectionHelpers
|
|
1224
|
+
.GetTypesFromAssemblyName("System.Core")
|
|
1225
|
+
.Take(10)
|
|
1226
|
+
.ToArray();
|
|
1227
|
+
Assert.IsNotNull(types);
|
|
1228
|
+
// May be empty on some platforms, but should not throw
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
[Test]
|
|
1232
|
+
public void GetTypesWithAttribute()
|
|
1233
|
+
{
|
|
1234
|
+
Type[] typesWithDescAttr = ReflectionHelpers
|
|
1235
|
+
.GetTypesWithAttribute<DescriptionAttribute>()
|
|
1236
|
+
.ToArray();
|
|
1237
|
+
Assert.IsNotNull(typesWithDescAttr);
|
|
1238
|
+
Assert.IsTrue(typesWithDescAttr.Contains(typeof(TestAttributeClass)));
|
|
1239
|
+
|
|
1240
|
+
Type[] typesByType = ReflectionHelpers
|
|
1241
|
+
.GetTypesWithAttribute(typeof(DescriptionAttribute))
|
|
1242
|
+
.ToArray();
|
|
1243
|
+
Assert.IsNotNull(typesByType);
|
|
1244
|
+
Assert.IsTrue(typesByType.Contains(typeof(TestAttributeClass)));
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
[Test]
|
|
1248
|
+
public void HasAttributeSafe()
|
|
1249
|
+
{
|
|
1250
|
+
Type testType = typeof(TestAttributeClass);
|
|
1251
|
+
FieldInfo staticField = testType.GetField(
|
|
1252
|
+
nameof(TestAttributeClass.StaticFieldWithAttribute)
|
|
1253
|
+
);
|
|
1254
|
+
MethodInfo instanceMethod = testType.GetMethod(
|
|
1255
|
+
nameof(TestAttributeClass.InstanceMethodWithAttribute)
|
|
1256
|
+
);
|
|
1257
|
+
|
|
1258
|
+
Assert.IsTrue(ReflectionHelpers.HasAttributeSafe<ReflectionTestAttribute>(testType));
|
|
1259
|
+
Assert.IsTrue(ReflectionHelpers.HasAttributeSafe<ReflectionTestAttribute>(staticField));
|
|
1260
|
+
Assert.IsTrue(
|
|
1261
|
+
ReflectionHelpers.HasAttributeSafe<ReflectionTestAttribute>(instanceMethod)
|
|
1262
|
+
);
|
|
1263
|
+
|
|
1264
|
+
Assert.IsTrue(
|
|
1265
|
+
ReflectionHelpers.HasAttributeSafe(testType, typeof(ReflectionTestAttribute))
|
|
1266
|
+
);
|
|
1267
|
+
Assert.IsTrue(
|
|
1268
|
+
ReflectionHelpers.HasAttributeSafe(staticField, typeof(ReflectionTestAttribute))
|
|
1269
|
+
);
|
|
1270
|
+
Assert.IsTrue(
|
|
1271
|
+
ReflectionHelpers.HasAttributeSafe(instanceMethod, typeof(ReflectionTestAttribute))
|
|
1272
|
+
);
|
|
1273
|
+
|
|
1274
|
+
// Test with types that don't have attributes
|
|
1275
|
+
Assert.IsFalse(
|
|
1276
|
+
ReflectionHelpers.HasAttributeSafe<ReflectionTestAttribute>(typeof(TestMethodClass))
|
|
1277
|
+
);
|
|
1278
|
+
Assert.IsFalse(
|
|
1279
|
+
ReflectionHelpers.HasAttributeSafe(
|
|
1280
|
+
typeof(TestMethodClass),
|
|
1281
|
+
typeof(ReflectionTestAttribute)
|
|
1282
|
+
)
|
|
1283
|
+
);
|
|
1284
|
+
|
|
1285
|
+
// Test with null (should return false, not throw)
|
|
1286
|
+
Assert.IsFalse(ReflectionHelpers.HasAttributeSafe<ReflectionTestAttribute>(null));
|
|
1287
|
+
Assert.IsFalse(
|
|
1288
|
+
ReflectionHelpers.HasAttributeSafe(null, typeof(ReflectionTestAttribute))
|
|
1289
|
+
);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
[Test]
|
|
1293
|
+
public void GetAttributeSafe()
|
|
1294
|
+
{
|
|
1295
|
+
Type testType = typeof(TestAttributeClass);
|
|
1296
|
+
FieldInfo instanceField = testType.GetField(
|
|
1297
|
+
nameof(TestAttributeClass.InstanceFieldWithAttribute)
|
|
1298
|
+
);
|
|
1299
|
+
|
|
1300
|
+
ReflectionTestAttribute classAttr =
|
|
1301
|
+
ReflectionHelpers.GetAttributeSafe<ReflectionTestAttribute>(testType);
|
|
1302
|
+
Assert.IsNotNull(classAttr);
|
|
1303
|
+
Assert.AreEqual("ClassLevel", classAttr.Name);
|
|
1304
|
+
Assert.AreEqual(10, classAttr.Value);
|
|
1305
|
+
|
|
1306
|
+
ReflectionTestAttribute fieldAttr =
|
|
1307
|
+
ReflectionHelpers.GetAttributeSafe<ReflectionTestAttribute>(instanceField);
|
|
1308
|
+
Assert.IsNotNull(fieldAttr);
|
|
1309
|
+
Assert.AreEqual("InstanceField", fieldAttr.Name);
|
|
1310
|
+
Assert.AreEqual(5, fieldAttr.Value);
|
|
1311
|
+
|
|
1312
|
+
// Test non-generic version
|
|
1313
|
+
Attribute classAttrObj = ReflectionHelpers.GetAttributeSafe(
|
|
1314
|
+
testType,
|
|
1315
|
+
typeof(ReflectionTestAttribute)
|
|
1316
|
+
);
|
|
1317
|
+
Assert.IsNotNull(classAttrObj);
|
|
1318
|
+
Assert.IsInstanceOf<ReflectionTestAttribute>(classAttrObj);
|
|
1319
|
+
|
|
1320
|
+
// Test with null
|
|
1321
|
+
Assert.IsNull(ReflectionHelpers.GetAttributeSafe<ReflectionTestAttribute>(null));
|
|
1322
|
+
Assert.IsNull(
|
|
1323
|
+
ReflectionHelpers.GetAttributeSafe(null, typeof(ReflectionTestAttribute))
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
[Test]
|
|
1328
|
+
public void GetAllAttributesSafe()
|
|
1329
|
+
{
|
|
1330
|
+
Type testType = typeof(TestAttributeClass);
|
|
1331
|
+
PropertyInfo instanceProperty = testType.GetProperty(
|
|
1332
|
+
nameof(TestAttributeClass.InstancePropertyWithAttribute)
|
|
1333
|
+
);
|
|
1334
|
+
|
|
1335
|
+
ReflectionTestAttribute[] typeAttrs = ReflectionHelpers
|
|
1336
|
+
.GetAllAttributesSafe<ReflectionTestAttribute>(testType)
|
|
1337
|
+
.ToArray();
|
|
1338
|
+
Assert.IsNotNull(typeAttrs);
|
|
1339
|
+
Assert.AreEqual(1, typeAttrs.Length);
|
|
1340
|
+
Assert.AreEqual("ClassLevel", typeAttrs[0].Name);
|
|
1341
|
+
|
|
1342
|
+
ReflectionTestAttribute[] propAttrs = ReflectionHelpers
|
|
1343
|
+
.GetAllAttributesSafe<ReflectionTestAttribute>(instanceProperty)
|
|
1344
|
+
.ToArray();
|
|
1345
|
+
Assert.IsNotNull(propAttrs);
|
|
1346
|
+
Assert.AreEqual(1, propAttrs.Length);
|
|
1347
|
+
Assert.AreEqual("InstanceProperty", propAttrs[0].Name);
|
|
1348
|
+
|
|
1349
|
+
// Test non-generic version
|
|
1350
|
+
Attribute[] allTypeAttrs = ReflectionHelpers.GetAllAttributesSafe(testType).ToArray();
|
|
1351
|
+
Assert.IsNotNull(allTypeAttrs);
|
|
1352
|
+
Assert.Greater(allTypeAttrs.Length, 0);
|
|
1353
|
+
|
|
1354
|
+
Attribute[] allPropAttrs = ReflectionHelpers
|
|
1355
|
+
.GetAllAttributesSafe(instanceProperty, typeof(ReflectionTestAttribute))
|
|
1356
|
+
.ToArray();
|
|
1357
|
+
Assert.IsNotNull(allPropAttrs);
|
|
1358
|
+
Assert.AreEqual(1, allPropAttrs.Length);
|
|
1359
|
+
|
|
1360
|
+
// Test with null
|
|
1361
|
+
Assert.AreEqual(
|
|
1362
|
+
0,
|
|
1363
|
+
ReflectionHelpers.GetAllAttributesSafe<ReflectionTestAttribute>(null).Length
|
|
1364
|
+
);
|
|
1365
|
+
Assert.AreEqual(0, ReflectionHelpers.GetAllAttributesSafe(null).Length);
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
[Test]
|
|
1369
|
+
public void GetAllAttributeValuesSafe()
|
|
1370
|
+
{
|
|
1371
|
+
Type testType = typeof(TestAttributeClass);
|
|
1372
|
+
Dictionary<string, object> attrValues = ReflectionHelpers.GetAllAttributeValuesSafe(
|
|
1373
|
+
testType
|
|
1374
|
+
);
|
|
1375
|
+
|
|
1376
|
+
Assert.IsNotNull(attrValues);
|
|
1377
|
+
Assert.IsTrue(attrValues.ContainsKey("ReflectionTest"));
|
|
1378
|
+
Assert.IsInstanceOf<ReflectionTestAttribute>(attrValues["ReflectionTest"]);
|
|
1379
|
+
|
|
1380
|
+
// Test with null
|
|
1381
|
+
Dictionary<string, object> nullResult = ReflectionHelpers.GetAllAttributeValuesSafe(
|
|
1382
|
+
null
|
|
1383
|
+
);
|
|
1384
|
+
Assert.IsNotNull(nullResult);
|
|
1385
|
+
Assert.AreEqual(0, nullResult.Count);
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
[Test]
|
|
1389
|
+
public void GetMembersWithAttributeSafe()
|
|
1390
|
+
{
|
|
1391
|
+
Type testType = typeof(TestAttributeClass);
|
|
1392
|
+
|
|
1393
|
+
MethodInfo[] methods = ReflectionHelpers
|
|
1394
|
+
.GetMethodsWithAttributeSafe<ReflectionTestAttribute>(testType)
|
|
1395
|
+
.ToArray();
|
|
1396
|
+
Assert.IsNotNull(methods);
|
|
1397
|
+
Assert.Greater(methods.Length, 0);
|
|
1398
|
+
Assert.IsTrue(
|
|
1399
|
+
methods.Any(m => m.Name == nameof(TestAttributeClass.StaticMethodWithAttribute))
|
|
1400
|
+
);
|
|
1401
|
+
Assert.IsTrue(
|
|
1402
|
+
methods.Any(m => m.Name == nameof(TestAttributeClass.InstanceMethodWithAttribute))
|
|
1403
|
+
);
|
|
1404
|
+
|
|
1405
|
+
PropertyInfo[] properties = ReflectionHelpers
|
|
1406
|
+
.GetPropertiesWithAttributeSafe<ReflectionTestAttribute>(testType)
|
|
1407
|
+
.ToArray();
|
|
1408
|
+
Assert.IsNotNull(properties);
|
|
1409
|
+
Assert.Greater(properties.Length, 0);
|
|
1410
|
+
Assert.IsTrue(
|
|
1411
|
+
properties.Any(p =>
|
|
1412
|
+
p.Name == nameof(TestAttributeClass.StaticPropertyWithAttribute)
|
|
1413
|
+
)
|
|
1414
|
+
);
|
|
1415
|
+
|
|
1416
|
+
FieldInfo[] fields = ReflectionHelpers
|
|
1417
|
+
.GetFieldsWithAttributeSafe<ReflectionTestAttribute>(testType)
|
|
1418
|
+
.ToArray();
|
|
1419
|
+
Assert.IsNotNull(fields);
|
|
1420
|
+
Assert.Greater(fields.Length, 0);
|
|
1421
|
+
Assert.IsTrue(
|
|
1422
|
+
fields.Any(f => f.Name == nameof(TestAttributeClass.StaticFieldWithAttribute))
|
|
1423
|
+
);
|
|
1424
|
+
|
|
1425
|
+
// Test with null
|
|
1426
|
+
Assert.AreEqual(
|
|
1427
|
+
0,
|
|
1428
|
+
ReflectionHelpers.GetMethodsWithAttributeSafe<ReflectionTestAttribute>(null).Length
|
|
1429
|
+
);
|
|
1430
|
+
Assert.AreEqual(
|
|
1431
|
+
0,
|
|
1432
|
+
ReflectionHelpers
|
|
1433
|
+
.GetPropertiesWithAttributeSafe<ReflectionTestAttribute>(null)
|
|
1434
|
+
.Length
|
|
1435
|
+
);
|
|
1436
|
+
Assert.AreEqual(
|
|
1437
|
+
0,
|
|
1438
|
+
ReflectionHelpers.GetFieldsWithAttributeSafe<ReflectionTestAttribute>(null).Length
|
|
1439
|
+
);
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
[Test]
|
|
1443
|
+
public void LoadStaticPropertiesForType()
|
|
1444
|
+
{
|
|
1445
|
+
Dictionary<string, PropertyInfo> staticProperties =
|
|
1446
|
+
ReflectionHelpers.LoadStaticPropertiesForType<TestPropertyClass>();
|
|
1447
|
+
Assert.IsNotNull(staticProperties);
|
|
1448
|
+
|
|
1449
|
+
// Note: This method looks for static properties that return the same type as the class
|
|
1450
|
+
// Our TestPropertyClass doesn't have static properties that return TestPropertyClass,
|
|
1451
|
+
// so the result should be empty, but the method should not throw
|
|
1452
|
+
Assert.IsNotNull(staticProperties);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
[Test]
|
|
1456
|
+
public void LoadStaticFieldsForType()
|
|
1457
|
+
{
|
|
1458
|
+
Dictionary<string, FieldInfo> staticFields =
|
|
1459
|
+
ReflectionHelpers.LoadStaticFieldsForType<TestPropertyClass>();
|
|
1460
|
+
Assert.IsNotNull(staticFields);
|
|
1461
|
+
|
|
1462
|
+
// Note: This method looks for static fields that are of the same type as the class
|
|
1463
|
+
// Our TestPropertyClass doesn't have such fields, so the result should be empty,
|
|
1464
|
+
// but the method should not throw
|
|
1465
|
+
Assert.IsNotNull(staticFields);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
[Test]
|
|
1469
|
+
public void IsAttributeDefined()
|
|
1470
|
+
{
|
|
1471
|
+
Type testType = typeof(TestAttributeClass);
|
|
1472
|
+
FieldInfo testField = testType.GetField(
|
|
1473
|
+
nameof(TestAttributeClass.InstanceFieldWithAttribute)
|
|
1474
|
+
);
|
|
1475
|
+
|
|
1476
|
+
// Test the extension method version
|
|
1477
|
+
Assert.IsTrue(testType.IsAttributeDefined(out ReflectionTestAttribute typeAttr));
|
|
1478
|
+
Assert.IsNotNull(typeAttr);
|
|
1479
|
+
Assert.AreEqual("ClassLevel", typeAttr.Name);
|
|
1480
|
+
Assert.AreEqual(10, typeAttr.Value);
|
|
1481
|
+
|
|
1482
|
+
Assert.IsTrue(testField.IsAttributeDefined(out ReflectionTestAttribute fieldAttr));
|
|
1483
|
+
Assert.IsNotNull(fieldAttr);
|
|
1484
|
+
Assert.AreEqual("InstanceField", fieldAttr.Name);
|
|
1485
|
+
Assert.AreEqual(5, fieldAttr.Value);
|
|
1486
|
+
|
|
1487
|
+
// Test with type that doesn't have the attribute
|
|
1488
|
+
Type methodType = typeof(TestMethodClass);
|
|
1489
|
+
Assert.IsFalse(methodType.IsAttributeDefined(out ReflectionTestAttribute noAttr));
|
|
1490
|
+
Assert.IsNull(noAttr);
|
|
1491
|
+
}
|
|
531
1492
|
}
|
|
532
1493
|
}
|