@@ -13,8 +13,8 @@ Every descriptor should inherit from `DescriptorBase`, this hides object members
13
13
----
14
14
var notDescriptors = new[] { typeof(ClusterProcessOpenFileDescriptors).Name, "DescriptorForAttribute" };
15
15
var descriptors = from t in typeof(DescriptorBase<,>).Assembly().Types()
16
- where t.IsClass()
17
- && t.Name.Contains("Descriptor")
16
+ where t.IsClass()
17
+ && t.Name.Contains("Descriptor")
18
18
&& !notDescriptors.Contains(t.Name)
19
19
&& !t.GetInterfaces().Any(i => i == typeof(IDescriptor))
20
20
select t.FullName;
@@ -59,3 +59,74 @@ var selectorMethods =
59
59
selectorMethods.Should().BeEmpty();
60
60
----
61
61
62
+ Descriptor methods that assign to a nullable bool property should accept
63
+ a nullable bool with a default value
64
+
65
+ [source,csharp]
66
+ ----
67
+ var queries =
68
+ from t in typeof(IQuery).Assembly().Types()
69
+ where t.IsInterface() && typeof(IQuery).IsAssignableFrom(t)
70
+ where t.GetProperties().Any(p => p.PropertyType == typeof(bool?))
71
+ select t;
72
+
73
+ var descriptors =
74
+ from t in typeof(DescriptorBase<,>).Assembly().Types()
75
+ where t.IsClass() && typeof(IDescriptor).IsAssignableFrom(t)
76
+ where t.GetInterfaces().Intersect(queries).Any()
77
+ select t;
78
+
79
+ var breakingDescriptors = new List<string>();
80
+
81
+ var parameterlessMethods = new List<MethodInfo>
82
+ {
83
+ typeof(BoolQueryDescriptor<>).GetMethod(nameof(BoolQueryDescriptor<object>.DisableCoord))
84
+ };
85
+
86
+ var nonDefaultValueMethods = new List<MethodInfo>
87
+ {
88
+ typeof(SpanNearQueryDescriptor<>).GetMethod(nameof(SpanNearQueryDescriptor<object>.CollectPayloads)),
89
+ typeof(SpanNearQueryDescriptor<>).GetMethod(nameof(SpanNearQueryDescriptor<object>.InOrder)),
90
+ };
91
+ ----
92
+
93
+ [source,csharp]
94
+ ----
95
+ foreach (var query in queries)
96
+ {
97
+ var descriptor = descriptors.First(d => query.IsAssignableFrom(d));
98
+ foreach (var boolProperty in query.GetProperties().Where(p => p.PropertyType == typeof(bool?)))
99
+ {
100
+ var descriptorMethod = descriptor.GetMethod(boolProperty.Name);
101
+ if (descriptorMethod == null)
102
+ throw new Exception($"No method for property {boolProperty.Name} on {descriptor.Name}");
103
+
104
+ var parameters = descriptorMethod.GetParameters();
105
+
106
+ if (!parameters.Any())
107
+ {
108
+ if (parameterlessMethods.Contains(descriptorMethod))
109
+ continue;
110
+
111
+ throw new Exception($"No parameter for method {descriptorMethod.Name} on {descriptor.Name}");
112
+ }
113
+
114
+ if (parameters.Length > 1)
115
+ throw new Exception($"More than one parameter for method {descriptorMethod.Name} on {descriptor.Name}");
116
+
117
+ if (parameters[0].ParameterType != typeof(bool?))
118
+ breakingDescriptors.Add($"{descriptor.FullName} method {descriptorMethod.Name} does not take nullable bool");
119
+
120
+ if (!parameters[0].HasDefaultValue)
121
+ {
122
+ if (nonDefaultValueMethods.Contains(descriptorMethod))
123
+ continue;
124
+
125
+ breakingDescriptors.Add($"{descriptor.FullName} method {descriptorMethod.Name} does not have a default value");
126
+ }
127
+ }
128
+ }
129
+
130
+ breakingDescriptors.Should().BeEmpty();
131
+ ----
132
+
0 commit comments