1 //
2 // TypedReferenceTest.cs
3 //
4 // Authors:
5 //  Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2015 Xamarin Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 // Licensed to the .NET Foundation under one or more agreements.
29 // See the LICENSE file in the project root for more information.
30 
31 using System.Collections.Generic;
32 using System.Reflection;
33 using Xunit;
34 
35 namespace System.Tests
36 {
37     public static class TypedReferenceTests
38     {
39         struct OneStruct
40         {
41             public string field;
42             public int b;
43         }
44 
45         class OtherType
46         {
47             public OneStruct oneStruct;
48         }
49 
50         [Fact]
NegativeMakeTypedReference()51         public static void NegativeMakeTypedReference()
52         {
53             OtherType data = new OtherType { oneStruct = new OneStruct { field = "field", b = 2343 } };
54             Type dataType = data.GetType();
55             Assert.Throws<ArgumentNullException>(() => { TypedReference.MakeTypedReference(null, dataType.GetFields()); });
56             Assert.Throws<ArgumentNullException>(() => { TypedReference.MakeTypedReference(data, null); });
57             AssertExtensions.Throws<ArgumentException>(null, () => { TypedReference.MakeTypedReference(data, Array.Empty<FieldInfo>()); });
58             AssertExtensions.Throws<ArgumentException>(null, () => { TypedReference.MakeTypedReference(data, new FieldInfo[] { dataType.GetField("oneStruct"), null }); });
59             AssertExtensions.Throws<ArgumentException>(null, () => { TypedReference.MakeTypedReference(data, new FieldInfo[] { dataType.GetField("oneStruct"), typeof(OneStruct).GetField("b") }); });
60         }
61 
62         [Fact]
MakeTypedReference_ToObjectTests()63         public static void MakeTypedReference_ToObjectTests()
64         {
65             OneStruct structObj = new OneStruct { field = "field", b = 2343 };
66             OtherType data = new OtherType { oneStruct = structObj };
67             Type dataType = data.GetType();
68             TypedReference reference = TypedReference.MakeTypedReference(data, new FieldInfo[] { dataType.GetField("oneStruct"), typeof(OneStruct).GetField("field") });
69             Assert.Equal("field", TypedReference.ToObject(reference));
70 
71             reference = TypedReference.MakeTypedReference(data, new FieldInfo[] { dataType.GetField("oneStruct") });
72             Assert.Equal(structObj, TypedReference.ToObject(reference));
73         }
74 
75 #if !uapaot  // ActiveIssue UapAot TFS 430781 - __makeref causes ILC fatal error.
76         [Fact]
GetTargetTypeTests()77         public static void GetTargetTypeTests()
78         {
79             int intValue = 13223;
80             TypedReference reference = __makeref(intValue);
81             Assert.Equal(intValue.GetType(), TypedReference.GetTargetType(reference));
82 
83             long lValue = long.MaxValue;
84             reference = __makeref(lValue);
85             Assert.Equal(lValue.GetType(), TypedReference.GetTargetType(reference));
86 
87             string strValue = "a value";
88             reference = __makeref(strValue);
89             Assert.Equal(strValue.GetType(), TypedReference.GetTargetType(reference));
90 
91             char charValue = 'A';
92             reference = __makeref(charValue);
93             Assert.Equal(charValue.GetType(), TypedReference.GetTargetType(reference));
94 
95             byte byteValue = byte.MaxValue;
96             reference = __makeref(byteValue);
97             Assert.Equal(byteValue.GetType(), TypedReference.GetTargetType(reference));
98 
99             double doubleValue = double.MaxValue;
100             reference = __makeref(doubleValue);
101             Assert.Equal(doubleValue.GetType(), TypedReference.GetTargetType(reference));
102 
103             float floatValue = float.MaxValue;
104             reference = __makeref(floatValue);
105             Assert.Equal(floatValue.GetType(), TypedReference.GetTargetType(reference));
106 
107             bool boolValue = true;
108             reference = __makeref(boolValue);
109             Assert.Equal(boolValue.GetType(), TypedReference.GetTargetType(reference));
110         }
111 #endif // !uapaot
112 
113 #if !uapaot  // ActiveIssue UapAot TFS 430781 - __makeref causes ILC fatal error.
114         [Fact]
PointerTypeTests()115         public static unsafe void PointerTypeTests()
116         {
117             void* pointerValue = (void*)0x123456;
118             TypedReference reference = __makeref(pointerValue);
119             Assert.Equal(typeof(void*), TypedReference.GetTargetType(reference));
120 
121             // Pointer types get boxed as UIntPtr
122             object obj = TypedReference.ToObject(reference);
123             Assert.Equal(typeof(UIntPtr), obj.GetType());
124             Assert.Equal((UIntPtr)pointerValue, (UIntPtr)obj);
125         }
126 #endif // !uapaot
127     }
128 }
129