Skip to content

Commit a2f2742

Browse files
committed
Add missed tests
1 parent f1e4d03 commit a2f2742

File tree

2 files changed

+327
-0
lines changed

2 files changed

+327
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Linq.Expressions;
6+
using Xunit;
7+
8+
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
9+
{
10+
public class MemberExpressionCacheKeyComparerTest
11+
{
12+
private readonly MemberExpressionCacheKeyComparer Comparer = MemberExpressionCacheKeyComparer.Instance;
13+
14+
[Fact]
15+
public void Equals_ReturnsTrue_ForTheSameExpression()
16+
{
17+
// Arrange
18+
var key = GetKey(m => m.Value);
19+
20+
// Act & Assert
21+
VerifyEquals(key, key);
22+
}
23+
24+
[Fact]
25+
public void Equals_ReturnsTrue_ForDifferentInstances_OfSameExpression()
26+
{
27+
// Arrange
28+
var key1 = GetKey(m => m.Value);
29+
var key2 = GetKey(m => m.Value);
30+
31+
// Act & Assert
32+
VerifyEquals(key1, key2);
33+
}
34+
35+
[Fact]
36+
public void Equals_ReturnsTrue_ForChainedMemberAccessExpressionsWithReferenceTypes()
37+
{
38+
// Arrange
39+
var key1 = GetKey(m => m.TestModel2.Name);
40+
var key2 = GetKey(m => m.TestModel2.Name);
41+
42+
// Act & Assert
43+
VerifyEquals(key1, key2);
44+
}
45+
46+
[Fact]
47+
public void Equals_ReturnsTrue_ForChainedMemberAccessExpressionsWithNullableValueTypes()
48+
{
49+
// Arrange
50+
var key1 = GetKey(m => m.NullableDateTime.Value.TimeOfDay);
51+
var key2 = GetKey(m => m.NullableDateTime.Value.TimeOfDay);
52+
53+
// Act & Assert
54+
VerifyEquals(key1, key2);
55+
}
56+
57+
[Fact]
58+
public void Equals_ReturnsTrue_ForChainedMemberAccessExpressionsWithValueTypes()
59+
{
60+
// Arrange
61+
var key1 = GetKey(m => m.DateTime.Year);
62+
var key2 = GetKey(m => m.DateTime.Year);
63+
64+
// Act & Assert
65+
VerifyEquals(key1, key2);
66+
}
67+
68+
[Fact]
69+
public void Equals_ReturnsFalse_ForDifferentExpression()
70+
{
71+
// Arrange
72+
var key1 = GetKey(m => m.Value);
73+
var key2 = GetKey(m => m.TestModel2.Name);
74+
75+
// Act & Assert
76+
VerifyNotEquals(key1, key2);
77+
}
78+
79+
[Fact]
80+
public void Equals_ReturnsFalse_ForChainedExpressions()
81+
{
82+
// Arrange
83+
var key1 = GetKey(m => m.TestModel2.Id);
84+
var key2 = GetKey(m => m.TestModel2.Name);
85+
86+
// Act & Assert
87+
VerifyNotEquals(key1, key2);
88+
}
89+
90+
[Fact]
91+
public void Equals_ReturnsFalse_ForChainedExpressions_WithValueTypes()
92+
{
93+
// Arrange
94+
var key1 = GetKey(m => m.DateTime.Ticks);
95+
var key2 = GetKey(m => m.DateTime.Year);
96+
97+
// Act & Assert
98+
VerifyNotEquals(key1, key2);
99+
}
100+
101+
[Fact]
102+
public void Equals_ReturnsFalse_ForChainedExpressions_DifferingByNullable()
103+
{
104+
// Arrange
105+
var key1 = GetKey(m => m.DateTime.Ticks);
106+
var key2 = GetKey(m => m.NullableDateTime.Value.Ticks);
107+
108+
// Act & Assert
109+
VerifyNotEquals(key1, key2);
110+
}
111+
112+
[Fact]
113+
public void Equals_ReturnsFalse_WhenOneExpressionIsSubsetOfOther()
114+
{
115+
// Arrange
116+
var key1 = GetKey(m => m.TestModel2);
117+
var key2 = GetKey(m => m.TestModel2.Name);
118+
119+
// Act & Assert
120+
VerifyNotEquals(key1, key2);
121+
}
122+
123+
[Fact]
124+
public void Equals_ReturnsFalse_WhenMemberIsAccessedThroughNullableProperty()
125+
{
126+
// Arrange
127+
var key1 = GetKey(m => m.NullableDateTime.Value.Year);
128+
var key2 = GetKey(m => m.DateTime.Year);
129+
130+
// Act
131+
VerifyNotEquals(key1, key2);
132+
}
133+
134+
[Fact]
135+
public void Equals_ReturnsFalse_WhenMemberIsAccessedThroughDifferentModels()
136+
{
137+
// Arrange
138+
var key1 = GetKey<TestModel2, int>(m => m.Id);
139+
var key2 = GetKey(m => m.TestModel2.Id);
140+
141+
// Act
142+
VerifyNotEquals(key1, key2);
143+
}
144+
145+
[Fact]
146+
public void Equals_ReturnsFalse_WhenMemberIsAccessedThroughConstantExpression()
147+
{
148+
// Arrange
149+
var testModel = new TestModel2 { Id = 1 };
150+
var key1 = GetKey(m => testModel.Id);
151+
var key2 = GetKey<TestModel2, int>(m => m.Id);
152+
153+
// Act
154+
VerifyNotEquals(key1, key2);
155+
}
156+
157+
private void VerifyEquals(MemberExpressionCacheKey key1, MemberExpressionCacheKey key2)
158+
{
159+
Assert.Equal(key1, key2, Comparer);
160+
161+
var hashCode1 = Comparer.GetHashCode(key1);
162+
var hashCode2 = Comparer.GetHashCode(key2);
163+
Assert.Equal(hashCode1, hashCode2);
164+
165+
var cachedKey1 = key1.MakeCacheable();
166+
167+
Assert.Equal(key1, cachedKey1, Comparer);
168+
Assert.Equal(cachedKey1, key1, Comparer);
169+
170+
var cachedKeyHashCode1 = Comparer.GetHashCode(cachedKey1);
171+
Assert.Equal(hashCode1, cachedKeyHashCode1);
172+
}
173+
174+
private void VerifyNotEquals(MemberExpressionCacheKey key1, MemberExpressionCacheKey key2)
175+
{
176+
var hashCode1 = Comparer.GetHashCode(key1);
177+
var hashCode2 = Comparer.GetHashCode(key2);
178+
179+
Assert.NotEqual(hashCode1, hashCode2);
180+
Assert.NotEqual(key1, key2, Comparer);
181+
182+
var cachedKey1 = key1.MakeCacheable();
183+
Assert.NotEqual(key2, cachedKey1, Comparer);
184+
185+
var cachedKeyHashCode1 = Comparer.GetHashCode(cachedKey1);
186+
Assert.NotEqual(cachedKeyHashCode1, hashCode2);
187+
}
188+
189+
private static MemberExpressionCacheKey GetKey<TResult>(Expression<Func<TestModel, TResult>> expression)
190+
=> GetKey<TestModel, TResult>(expression);
191+
192+
private static MemberExpressionCacheKey GetKey<TModel, TResult>(Expression<Func<TModel, TResult>> expression)
193+
{
194+
var memberExpression = Assert.IsAssignableFrom<MemberExpression>(expression.Body);
195+
return new MemberExpressionCacheKey(typeof(TModel), memberExpression);
196+
}
197+
198+
public class TestModel
199+
{
200+
public string Value { get; set; }
201+
202+
public TestModel2 TestModel2 { get; set; }
203+
204+
public DateTime DateTime { get; set; }
205+
206+
public DateTime? NullableDateTime { get; set; }
207+
}
208+
209+
public class TestModel2
210+
{
211+
public string Name { get; set; }
212+
213+
public int Id { get; set; }
214+
}
215+
}
216+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq.Expressions;
7+
using System.Reflection;
8+
using Xunit;
9+
10+
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
11+
{
12+
public class MemberExpressionCacheKeyTest
13+
{
14+
[Fact]
15+
public void GetEnumerator_ReturnsMembers()
16+
{
17+
// Arrange
18+
var expected = new[]
19+
{
20+
typeof(TestModel3).GetProperty(nameof(TestModel3.Value)),
21+
typeof(TestModel2).GetProperty(nameof(TestModel2.TestModel3)),
22+
typeof(TestModel).GetProperty(nameof(TestModel.TestModel2)),
23+
};
24+
25+
var key = GetKey(m => m.TestModel2.TestModel3.Value);
26+
27+
// Act
28+
var actual = GetMembers(key);
29+
30+
// Assert
31+
Assert.Equal(expected, actual);
32+
}
33+
34+
[Fact]
35+
public void GetEnumerator_WithNullableType_ReturnsMembers()
36+
{
37+
// Arrange
38+
var expected = new[]
39+
{
40+
typeof(DateTime).GetProperty(nameof(DateTime.Ticks)),
41+
typeof(DateTime?).GetProperty(nameof(Nullable<DateTime>.Value)),
42+
typeof(TestModel).GetProperty(nameof(TestModel.NullableDateTime)),
43+
};
44+
45+
var key = GetKey(m => m.NullableDateTime.Value.Ticks);
46+
47+
// Act
48+
var actual = GetMembers(key);
49+
50+
// Assert
51+
Assert.Equal(expected, actual);
52+
}
53+
54+
[Fact]
55+
public void GetEnumerator_WithValueType_ReturnsMembers()
56+
{
57+
// Arrange
58+
var expected = new[]
59+
{
60+
typeof(DateTime).GetProperty(nameof(DateTime.Ticks)),
61+
typeof(TestModel).GetProperty(nameof(TestModel.DateTime)),
62+
};
63+
64+
var key = GetKey(m => m.DateTime.Ticks);
65+
66+
// Act
67+
var actual = GetMembers(key);
68+
69+
// Assert
70+
Assert.Equal(expected, actual);
71+
}
72+
73+
private static MemberExpressionCacheKey GetKey<TResult>(Expression<Func<TestModel, TResult>> expression)
74+
{
75+
var memberExpression = Assert.IsAssignableFrom<MemberExpression>(expression.Body);
76+
return new MemberExpressionCacheKey(typeof(TestModel), memberExpression);
77+
}
78+
79+
private static IList<MemberInfo> GetMembers(MemberExpressionCacheKey key)
80+
{
81+
var members = new List<MemberInfo>();
82+
foreach (var member in key)
83+
{
84+
members.Add(member);
85+
}
86+
87+
return members;
88+
}
89+
90+
public class TestModel
91+
{
92+
public TestModel2 TestModel2 { get; set; }
93+
94+
public DateTime DateTime { get; set; }
95+
96+
public DateTime? NullableDateTime { get; set; }
97+
}
98+
99+
public class TestModel2
100+
{
101+
public string Name { get; set; }
102+
103+
public TestModel3 TestModel3 { get; set; }
104+
}
105+
106+
public class TestModel3
107+
{
108+
public string Value { get; set; }
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)