1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Xunit;
namespace System.ComponentModel.DataAnnotations
{
public class EnumDataTypeAttributeTests
{
private static readonly ValidationContext s_testValidationContext = new ValidationContext(new object());
[Fact]
public static void EnumDataTypeAttribute_creation_DataType_and_CustomDataType()
{
var attribute = new EnumDataTypeAttribute(null);
Assert.Equal(DataType.Custom, attribute.DataType);
Assert.Equal("Enumeration", attribute.CustomDataType);
}
[Fact]
public static void Can_get_EnumType()
{
var attribute = new EnumDataTypeAttribute(null);
Assert.Null(attribute.EnumType);
attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
Assert.Equal(typeof(NonFlagsEnumType), attribute.EnumType);
}
[Fact]
public static void Validate_successful_for_null_value()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
AssertEx.DoesNotThrow(() => attribute.Validate(null, s_testValidationContext)); // Null is valid
}
[Fact]
public static void Validate_throws_InvalidOperationException_for_null_EnumType()
{
var attribute = new EnumDataTypeAttribute(null);
Assert.Null(attribute.EnumType);
Assert.Throws<InvalidOperationException>(
() => attribute.Validate("Value does not matter - EnumType is null", s_testValidationContext));
}
[Fact]
public static void Validate_throws_InvalidOperationException_for_non_enum_EnumType()
{
var attribute = new EnumDataTypeAttribute(typeof(string));
Assert.Equal(typeof(string), attribute.EnumType);
Assert.Throws<InvalidOperationException>(
() => attribute.Validate("Value does not matter - EnumType is not an enum", s_testValidationContext));
}
[Fact]
public static void Validate_throws_InvalidOperationException_for_Nullable_EnumType()
{
var attribute = new EnumDataTypeAttribute(typeof(Nullable<NonFlagsEnumType>));
Assert.Throws<InvalidOperationException>(
() => attribute.Validate("Value does not matter - EnumType is Nullable", s_testValidationContext));
attribute = new EnumDataTypeAttribute(typeof(Nullable<FlagsEnumType>));
Assert.Throws<InvalidOperationException>(
() => attribute.Validate("Value does not matter - EnumType is Nullable", s_testValidationContext));
}
[Fact]
public static void Validate_successful_for_null_or_empty_value()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
AssertEx.DoesNotThrow(() => attribute.Validate(null, s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate(string.Empty, s_testValidationContext));
}
[Fact]
public static void Validate_throws_for_non_matching_EnumType()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate(FlagsEnumType.X, s_testValidationContext));
}
[Fact]
public static void Validate_throws_for_non_ValueType_value()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate(new object(), s_testValidationContext));
}
[Fact]
public static void Validate_throws_for_non_integral_values()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate(true, s_testValidationContext)); // bool
Assert.Throws<ValidationException>(() => attribute.Validate(1.1f, s_testValidationContext)); // float
Assert.Throws<ValidationException>(() => attribute.Validate(123.456d, s_testValidationContext)); // double
Assert.Throws<ValidationException>(() => attribute.Validate(123.456m, s_testValidationContext)); // decimal
Assert.Throws<ValidationException>(() => attribute.Validate('0', s_testValidationContext)); // char
}
[Fact]
public static void Validate_successful_for_matching_non_flags_enums_and_matching_values()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
AssertEx.DoesNotThrow(() => attribute.Validate(NonFlagsEnumType.A, s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate(10, s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate(100, s_testValidationContext));
}
[Fact]
public static void Validate_successful_for_matching_flags_enums_and_matching_values()
{
var attribute = new EnumDataTypeAttribute(typeof(FlagsEnumType));
AssertEx.DoesNotThrow(() => attribute.Validate(FlagsEnumType.X, s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate(FlagsEnumType.X | FlagsEnumType.Y, s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate(5, s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate(7, s_testValidationContext));
}
[Fact]
public static void Validate_throws_for_matching_non_flags_enums_and_non_matching_values()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate(42, s_testValidationContext));
}
[Fact]
public static void Validate_throws_for_matching_flags_enums_and_non_matching_values()
{
var attribute = new EnumDataTypeAttribute(typeof(FlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate(0, s_testValidationContext));
Assert.Throws<ValidationException>(() => attribute.Validate(8, s_testValidationContext));
}
[Fact]
public static void Validate_successful_for_string_values_which_can_be_converted_to_enum_values()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
AssertEx.DoesNotThrow(() => attribute.Validate("A", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("B", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("C", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("0", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("10", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("100", s_testValidationContext));
attribute = new EnumDataTypeAttribute(typeof(FlagsEnumType));
AssertEx.DoesNotThrow(() => attribute.Validate("X", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("X, Y", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("X, Y, Z", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("1", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("5", s_testValidationContext));
AssertEx.DoesNotThrow(() => attribute.Validate("7", s_testValidationContext));
}
[Fact]
public static void Validate_throws_for_string_values_which_cannot_be_converted_to_enum_values()
{
var attribute = new EnumDataTypeAttribute(typeof(NonFlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate("NonExist", s_testValidationContext));
Assert.Throws<ValidationException>(() => attribute.Validate("42", s_testValidationContext));
attribute = new EnumDataTypeAttribute(typeof(FlagsEnumType));
Assert.Throws<ValidationException>(() => attribute.Validate("NonExist", s_testValidationContext));
Assert.Throws<ValidationException>(() => attribute.Validate("0", s_testValidationContext));
Assert.Throws<ValidationException>(() => attribute.Validate("8", s_testValidationContext));
}
private enum NonFlagsEnumType
{
A = 0,
B = 10,
C = 100
}
[Flags]
private enum FlagsEnumType
{
X = 1,
Y = 2,
Z = 4
}
}
}
|