Skip to content

Commit d1e3c25

Browse files
committed
More AOT tests
1 parent 007d8a0 commit d1e3c25

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
using System.Runtime.CompilerServices;
2+
using System.Runtime.InteropServices;
3+
4+
namespace DotNext.Runtime;
5+
6+
[TestClass]
7+
public class ValueReferenceTests
8+
{
9+
[TestMethod]
10+
public void MutableFieldRef()
11+
{
12+
var obj = new MyClass { AnotherField = string.Empty };
13+
var reference = new ValueReference<int>(obj, ref obj.Field);
14+
15+
obj.Field = 20;
16+
Assert.AreEqual(obj.Field, reference.Value);
17+
18+
reference.Value = 42;
19+
Assert.AreEqual(obj.Field, reference.Value);
20+
Assert.IsTrue(string.IsNullOrEmpty(obj.AnotherField));
21+
}
22+
23+
[TestMethod]
24+
public void ImmutableFieldRef()
25+
{
26+
var obj = new MyClass { AnotherField = string.Empty };
27+
var reference = new ReadOnlyValueReference<int>(obj, in obj.Field);
28+
29+
obj.Field = 20;
30+
Assert.AreEqual(obj.Field, reference.Value);
31+
32+
Assert.AreEqual(obj.Field, reference.Value);
33+
Assert.IsTrue(string.IsNullOrEmpty(obj.AnotherField));
34+
}
35+
36+
[TestMethod]
37+
public void MutableToImmutableRef()
38+
{
39+
var obj = new MyClass { AnotherField = string.Empty };
40+
var reference = new ValueReference<int>(obj, ref obj.Field);
41+
ReadOnlyValueReference<int> roReference = reference;
42+
43+
obj.Field = 20;
44+
Assert.AreEqual(roReference.Value, reference.Value);
45+
46+
reference.Value = 42;
47+
Assert.AreEqual(roReference.Value, reference.Value);
48+
}
49+
50+
[TestMethod]
51+
public void MutableRefEquality()
52+
{
53+
var obj = new MyClass { AnotherField = string.Empty };
54+
var reference1 = new ValueReference<int>(obj, ref obj.Field);
55+
var reference2 = new ValueReference<int>(obj, ref obj.Field);
56+
57+
Assert.AreEqual(reference1, reference2);
58+
}
59+
60+
[TestMethod]
61+
public void ImmutableRefEquality()
62+
{
63+
var obj = new MyClass { AnotherField = string.Empty };
64+
var reference1 = new ReadOnlyValueReference<int>(obj, in obj.Field);
65+
var reference2 = new ReadOnlyValueReference<int>(obj, in obj.Field);
66+
67+
Assert.AreEqual(reference1, reference2);
68+
}
69+
70+
[TestMethod]
71+
public void ReferenceToArray()
72+
{
73+
var array = new string[1];
74+
var reference = new ValueReference<string>(array, 0)
75+
{
76+
Value = "Hello, world!"
77+
};
78+
79+
Assert.AreSame(array[0], reference.Value);
80+
Assert.AreSame(array[0], reference.ToString());
81+
}
82+
83+
[TestMethod]
84+
public void MutableEmptyRef()
85+
{
86+
var reference = default(ValueReference<string>);
87+
Assert.IsTrue(reference.IsEmpty);
88+
Assert.IsNull(reference.ToString());
89+
90+
Span<string> span = reference;
91+
Assert.IsTrue(span.IsEmpty);
92+
93+
Assert.ThrowsException<NullReferenceException>((Func<string>)reference);
94+
Assert.ThrowsException<NullReferenceException>(((Action<string>)reference).Bind(string.Empty));
95+
}
96+
97+
[TestMethod]
98+
public void ImmutableEmptyRef()
99+
{
100+
var reference = default(ReadOnlyValueReference<string>);
101+
Assert.IsTrue(reference.IsEmpty);
102+
Assert.IsNull(reference.ToString());
103+
104+
ReadOnlySpan<string> span = reference;
105+
Assert.IsTrue(span.IsEmpty);
106+
107+
Assert.ThrowsException<NullReferenceException>((Func<string>)reference);
108+
}
109+
110+
[TestMethod]
111+
public void AnonymousValue()
112+
{
113+
var reference = new ValueReference<int>(42);
114+
Assert.AreEqual(42, reference.Value);
115+
116+
((Action<int>)reference).Invoke(52);
117+
Assert.AreEqual(52, ToFunc<ValueReference<int>, int>(reference).Invoke());
118+
119+
ReadOnlyValueReference<int> roRef = reference;
120+
Assert.AreEqual(52, roRef.Value);
121+
Assert.AreEqual(52, ToFunc<ReadOnlyValueReference<int>, int>(reference).Invoke());
122+
}
123+
124+
private static Func<T> ToFunc<TSupplier, T>(TSupplier supplier)
125+
where TSupplier : ISupplier<T>
126+
=> supplier.ToDelegate();
127+
128+
[TestMethod]
129+
public void IncorrectReference()
130+
{
131+
byte[] empty = [];
132+
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ValueReference<byte>(empty, ref MemoryMarshal.GetArrayDataReference(empty)));
133+
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlyValueReference<byte>(empty, ref MemoryMarshal.GetArrayDataReference(empty)));
134+
}
135+
136+
[TestMethod]
137+
public void ReferenceSize()
138+
{
139+
Assert.AreEqual(Unsafe.SizeOf<ValueReference<float>>(), nint.Size + nint.Size);
140+
}
141+
142+
[TestMethod]
143+
public void BoxedValueInterop()
144+
{
145+
var boxedInt = BoxedValue<int>.Box(42);
146+
ValueReference<int> reference = boxedInt;
147+
148+
boxedInt.Value = 56;
149+
Assert.AreEqual(boxedInt.Value, reference.Value);
150+
}
151+
152+
[TestMethod]
153+
public void ArrayCovariance()
154+
{
155+
string[] array = ["a", "b"];
156+
Assert.ThrowsException<ArrayTypeMismatchException>(() => new ValueReference<object>(array, 0));
157+
158+
var roRef = new ReadOnlyValueReference<object>(array, 1);
159+
Assert.AreEqual("b", roRef.Value);
160+
}
161+
162+
[TestMethod]
163+
public void SpanInterop()
164+
{
165+
var reference = new ValueReference<int>(42);
166+
Span<int> span = reference;
167+
Assert.AreEqual(1, span.Length);
168+
169+
Assert.IsTrue(Unsafe.AreSame(in reference.Value, in span[0]));
170+
}
171+
172+
[TestMethod]
173+
public void ReadOnlySpanInterop()
174+
{
175+
ReadOnlyValueReference<int> reference = new ValueReference<int>(42);
176+
ReadOnlySpan<int> span = reference;
177+
Assert.AreEqual(1, span.Length);
178+
179+
Assert.IsTrue(Unsafe.AreSame(in reference.Value, in span[0]));
180+
}
181+
182+
private record MyClass
183+
{
184+
internal int Field;
185+
internal string? AnotherField;
186+
}
187+
}

0 commit comments

Comments
 (0)