• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

AndreuCodina / CrossValidation / 5848365906

13 Aug 2023 04:20PM UTC coverage: 95.391% (-0.5%) from 95.865%
5848365906

Pull #69

github

web-flow
Merge 3209d6e3b into d30b8b561
Pull Request #69: Add Apply

422 of 466 branches covered (90.56%)

Branch coverage included in aggregate %.

10 of 10 new or added lines in 2 files covered. (100.0%)

1275 of 1313 relevant lines covered (97.11%)

192.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.93
/src/CrossValidation/Validations/ValidationExtensions.cs
1
using System.Diagnostics.CodeAnalysis;
2
using System.Numerics;
3
using CrossValidation.Validators.BooleanValidators;
4
using CrossValidation.Validators.CollectionValidators;
5
using CrossValidation.Validators.ComparisonValidators;
6
using CrossValidation.Validators.EnumValidators;
7
using CrossValidation.Validators.NullValidators;
8
using CrossValidation.Validators.RegularExpressionValidators;
9
using CrossValidation.Validators.StringValidators;
10

11
namespace CrossValidation.Validations;
12

13
public static class ValidationExtensions
14
{
15
    public static IValidation<TField> NotNull<TField>(
16
        this IValidation<TField?> validation)
17
        where TField : class
18
    {
19

20
        return validation.SetValidator(() => new NotNullValidator<TField?>(validation.GetFieldValue()))
75✔
21
            .Transform(x => x!);
57✔
22
    }
23

24
    public static IValidation<TField> NotNull<TField>(
25
        this IValidation<TField?> validation)
26
        where TField : struct
27
    {
28
        return validation.SetValidator(() => new NotNullValidator<TField?>(validation.GetFieldValue()))
36✔
29
            .Transform(x => x!.Value);
22✔
30
    }
31

32
    public static IValidation<TField?> WhenNotNull<TField, TReturnedField>(
33
        this IValidation<TField?> validation,
34
        Func<IValidation<TField>, IValidation<TReturnedField>> action)
35
        where TField : struct
36
    {
37
        validation.Condition = () => validation.GetFieldValue() is not null;
59✔
38
        return validation.SetScope(() =>
32✔
39
        {
32✔
40
            validation.IsScopeCreator = true;
23✔
41
            var getFieldValue = () => validation.GetFieldValue()!.Value;
77✔
42
            var scopeValidation = CreateScopeValidation(
23✔
43
                validation: validation,
23✔
44
                getFieldValue: getFieldValue,
23✔
45
                index: validation.Index,
23✔
46
                fieldPathToOverride: null);
23✔
47
            action(scopeValidation);
23✔
48
        }, ScopeType.WhenNotNull);
52✔
49
    }
50

51
    public static IValidation<TField?> WhenNotNull<TField, TReturnedField>(
52
        this IValidation<TField?> validation,
53
        Func<IValidation<TField>, IValidation<TReturnedField>> action)
54
        where TField : class
55
    {
56
        validation.Condition = () => validation.GetFieldValue() is not null;
26✔
57
        return validation.SetScope(() =>
13✔
58
        {
13✔
59
            validation.IsScopeCreator = true;
11✔
60
            var getFieldValue = () => validation.GetFieldValue()!;
40✔
61
            var scopeValidation = CreateScopeValidation(
11✔
62
                validation: validation,
11✔
63
                getFieldValue: getFieldValue,
11✔
64
                index: validation.Index,
11✔
65
                fieldPathToOverride: null);
11✔
66
            action(scopeValidation);
11✔
67
        }, ScopeType.WhenNotNull);
23✔
68
    }
69

70
    public static IValidation<TField?> Null<TField>(
71
        this IValidation<TField?> validation)
72
        where TField : class
73
    {
74
        return validation.SetValidator(() => new NullValidator<TField?>(validation.GetFieldValue()));
16✔
75
    }
76

77
    public static IValidation<TField?> Null<TField>(
78
        this IValidation<TField?> validation)
79
        where TField : struct
80
    {
81
        return validation.SetValidator(() => new NullValidator<TField?>(validation.GetFieldValue()));
6✔
82
    }
83

84
    public static IValidation<TField> GreaterThan<TField>(
85
        this IValidation<TField> validation,
86
        TField valueToCompare)
87
        where TField : IComparisonOperators<TField, TField, bool>
88
    {
89
        return validation.SetValidator(() =>
115✔
90
            new GreaterThanValidator<TField>(validation.GetFieldValue(), valueToCompare));
221✔
91
    }
92

93
    public static IValidation<TField> Enum<TField>(
94
        this IValidation<TField> validation)
95
        where TField : Enum
96
    {
97
        return validation.SetValidator(() => new EnumValidator<TField>(validation.GetFieldValue(), typeof(TField)));
4✔
98
    }
99

100
    public static IValidation<TEnum> Enum<TEnum>(
101
        this IValidation<int> validation)
102
        where TEnum : Enum
103
    {
104
        return validation.SetValidator(() => new EnumValidator<int>(validation.GetFieldValue(), typeof(TEnum)))
4✔
105
            .Transform(x => (TEnum)(object)x);
2✔
106
    }
107

108
    public static IValidation<TEnum> Enum<TEnum>(
109
        this IValidation<string> validation)
110
        where TEnum : Enum
111
    {
112
        return validation.SetValidator(() => new EnumValidator<string>(validation.GetFieldValue(), typeof(TEnum)))
6✔
113
            .Transform(x => (TEnum)System.Enum.Parse(typeof(TEnum), x, ignoreCase: true));
4✔
114
    }
115

116
    public static IValidation<TField> Enum<TField>(
117
        this IValidation<TField> validation,
118
        params TField[] allowedValues)
119
        where TField : Enum
120
    {
121
        return validation.SetValidator(() =>
3✔
122
            new EnumRangeValidator<TField, TField>(validation.GetFieldValue(), allowedValues));
6✔
123
    }
124

125
    public static IValidation<TEnum> Enum<TEnum>(
126
        this IValidation<int> validation,
127
        params TEnum[] allowedValues)
128
        where TEnum : Enum
129
    {
130
        return validation
2✔
131
            .SetValidator(() => new EnumRangeValidator<int, TEnum>(validation.GetFieldValue(), allowedValues))
2✔
132
            .Transform(x => (TEnum)(object)x);
2✔
133
    }
134

135
    public static IValidation<TEnum> Enum<TEnum>(
136
        this IValidation<string> validation,
137
        params TEnum[] allowedValues)
138
        where TEnum : Enum
139
    {
140
        return validation.SetValidator(
2✔
141
                () => new EnumRangeValidator<string, TEnum>(validation.GetFieldValue(), allowedValues))
2✔
142
            .Transform(x => (TEnum)System.Enum.Parse(typeof(TEnum), x, ignoreCase: true));
2✔
143
    }
144

145
    public static IValidation<string> LengthRange(
146
        this IValidation<string> validation,
147
        int minimum,
148
        int maximum)
149
    {
150
        return validation.SetValidator(() => new LengthRangeValidator(validation.GetFieldValue(), minimum, maximum));
7✔
151
    }
152

153
    public static IValidation<string> MinimumLength(
154
        this IValidation<string> validation,
155
        int minimum)
156
    {
157
        return validation.SetValidator(() => new MinimumLengthValidator(validation.GetFieldValue(), minimum));
2✔
158
    }
159
    
160
    public static IValidation<string> MaximumLength(
161
        this IValidation<string> validation,
162
        int maximum)
163
    {
164
        return validation.SetValidator(() => new MaximumLengthValidator(validation.GetFieldValue(), maximum));
2✔
165
    }
166

167
    public static IValidation<IEnumerable<TInnerType>> ForEach<TInnerType, TReturnedField>(
168
        this IValidation<IEnumerable<TInnerType>> validation,
169
        Func<IValidation<TInnerType>, IValidation<TReturnedField>> action)
170
    {
171
        return validation.SetScope(() =>
42✔
172
        {
42✔
173
            validation.IsScopeCreator = true;
41✔
174
            var fieldCollection = validation.GetFieldValue()
41✔
175
                .ToList();
41✔
176
            var index = 0;
41✔
177
            var totalItems = fieldCollection.Count();
41✔
178

42✔
179
            foreach (var innerField in fieldCollection)
219!
180
            {
42✔
181
                var getFieldValue = () => innerField;
270✔
182
                var scopeValidation = CreateScopeValidation(
89✔
183
                    validation: validation,
89✔
184
                    getFieldValue: getFieldValue,
89✔
185
                    index: index,
89✔
186
                    fieldPathToOverride: validation.GetFieldPathWithIndex(validation.FieldPath, index));
89✔
187
                scopeValidation.HasFailed = false;
89✔
188
                action(scopeValidation);
89✔
189
                index++;
78✔
190
                var areAllItemsIterated = index  == totalItems;
78✔
191
                var stopWithFailedScope =
78✔
192
                    validation.HasFailed
78✔
193
                    && validation.Context!.ValidationMode is ValidationMode.AccumulateFirstErrors;
78✔
194
            
42✔
195
                if (areAllItemsIterated || stopWithFailedScope)
78✔
196
                {
42✔
197
                    validation.HasBeenExecuted = true;
30✔
198
                    break;
30✔
199
                }
42✔
200
            }
42✔
201
        }, ScopeType.ForEach);
72✔
202
    }
203

204
    public static IValidation<string> Regex(
205
        this IValidation<string> validation,
206
        [StringSyntax(StringSyntaxAttribute.Regex)]
207
        string pattern)
208
    {
209
        return validation.SetValidator(() => new RegularExpressionValidator(validation.GetFieldValue(), pattern));
4✔
210
    }
211
    
212
    public static IValidation<string> Empty(this IValidation<string> validation)
213
    {
214
        return validation.SetValidator(() => new EmptyStringValidator(validation.GetFieldValue()));
4✔
215
    }
216
    
217
    public static IValidation<IEnumerable<TField>> Empty<TField>(this IValidation<IEnumerable<TField>> validation)
218
    {
219
        return validation.SetValidator(() => new EmptyCollectionValidator<TField>(validation.GetFieldValue()));
4✔
220
    }
221
    
222
    public static IValidation<string> NotEmpty(this IValidation<string> validation)
223
    {
224
        return validation.SetValidator(() => new NotEmptyStringValidator(validation.GetFieldValue()));
4✔
225
    }
226
    
227
    public static IValidation<IEnumerable<TField>> NotEmpty<TField>(this IValidation<IEnumerable<TField>> validation)
228
    {
229
        return validation.SetValidator(() => new NotEmptyCollectionValidator<TField>(validation.GetFieldValue()));
4✔
230
    }
231

232
    public static IValidation<bool> True(this IValidation<bool> validation)
233
    {
234
        return validation.SetValidator(() => new TrueBooleanValidator(validation.GetFieldValue()));
4✔
235
    }
236
    
237
    public static IValidation<bool> False(this IValidation<bool> validation)
238
    {
239
        return validation.SetValidator(() => new FalseBooleanValidator(validation.GetFieldValue()));
4✔
240
    }
241
    
242
    public static void Apply<TField>(
243
        this IValidation<TField> validation,
244
        Action<IValidation<TField>> applyFunction)
245
    {
246
        applyFunction(validation);
1✔
247
    }
×
248
    
249
    public static IValidation<TResultField> Apply<TOriginalField, TResultField>(
250
        this IValidation<TOriginalField> validation,
251
        Func<IValidation<TOriginalField>, IValidation<TResultField>> applyFunction)
252
    {
253
        return applyFunction(validation);
1✔
254
    }
255

256
    internal static IValidation<TDependentField> CreateScopeValidation<TField, TDependentField>(
257
        this IValidation<TField> validation,
258
        Func<TDependentField> getFieldValue,
259
        int? index,
260
        string? fieldPathToOverride)
261
    {
262
        var scopeValidation = new Validation<TDependentField>(
232✔
263
            getFieldValue: getFieldValue,
232✔
264
            customThrowToThrow: validation.CustomExceptionToThrow,
232✔
265
            createGenericError: validation.CreateGenericError,
232✔
266
            fieldPath: fieldPathToOverride ?? validation.FieldPath,
232✔
267
            context: validation.Context,
232✔
268
            index: index,
232✔
269
            parentPath: validation.ParentPath,
232✔
270
            fixedException: validation.Context!.Exception,
232✔
271
            fixedMessage: validation.Context!.Message,
232✔
272
            fixedCode: validation.Context!.Code,
232✔
273
            fixedDetails: validation.Context!.Details,
232✔
274
            fixedStatusCode: validation.Context!.StatusCode,
232✔
275
            fixedFieldDisplayName: validation.Context!.FieldDisplayName);
232✔
276
        scopeValidation.HasFailed = validation.HasFailed;
232✔
277
        scopeValidation.HasPendingAsyncValidation = validation.HasPendingAsyncValidation;
232✔
278
        scopeValidation.ScopeType = validation.ScopeType;
232✔
279
        scopeValidation.IsInsideScope = true;
232✔
280
        scopeValidation.ScopeCreatorValidation = validation;
232✔
281
        validation.ScopeValidations ??= new();
232✔
282
        validation.ScopeValidations.Add(scopeValidation);
232✔
283
        return scopeValidation;
232✔
284
    }
285

286
    internal static string? GetFieldPathWithIndex<TField>(
287
        this IValidation<TField> validation,
288
        string? fieldPath,
289
        int? index)
290
    {
291
        if (fieldPath is null)
89✔
292
        {
293
            return null;
36✔
294
        }
295
        
296
        var indexRepresentation = index is not null ? $"[{index}]" : null;
53!
297
        return $"{fieldPath}{indexRepresentation}";
53✔
298
    }
299
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc