diff --git a/.editorconfig b/.editorconfig index 760c8cc..7536cf0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -306,3 +306,13 @@ dotnet_diagnostic.CA2000.severity = error # CA2000: Dispose object dotnet_diagnostic.CA1515.severity = none # CA1515: Consider making public types internal dotnet_diagnostic.CA1708.severity = none # CA1708: Identifiers should differ by more than case dotnet_diagnostic.CA1716.severity = none # CA1716: Identifiers should not match keywords + +MA0053.public_class_should_be_sealed = true +MA0053.exceptions_should_be_sealed = true + +dotnet_diagnostic.MA0004.severity = none +dotnet_diagnostic.MA0023.severity = none +dotnet_diagnostic.MA0048.severity = none +dotnet_diagnostic.MA0051.severity = none +dotnet_diagnostic.MA0053.severity = warning +dotnet_diagnostic.MA0071.severity = none diff --git a/Directory.Packages.props b/Directory.Packages.props index d5bb3b8..ffb73cf 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -34,4 +34,8 @@ + + + + diff --git a/src/Common/ITypeSymbolExtensions.cs b/src/Common/ITypeSymbolExtensions.cs index ac0c43f..a6e9186 100644 --- a/src/Common/ITypeSymbolExtensions.cs +++ b/src/Common/ITypeSymbolExtensions.cs @@ -53,21 +53,15 @@ public static IEnumerable GetBaseTypesAndThis(this ITypeSymbol? typ } } - public static IEnumerable GetAllMembers(this ITypeSymbol type) - { - if (type is { TypeKind: TypeKind.Interface }) - { - return type.AllInterfaces + public static IEnumerable GetAllMembers(this ITypeSymbol type) => + type is { TypeKind: TypeKind.Interface } + ? type + .AllInterfaces .SelectMany(i => i.GetMembers()) - .Concat(type.GetMembers()); - } - else - { - return type + .Concat(type.GetMembers()) + : type .GetBaseTypesAndThis() .SelectMany(t => t.GetMembers()); - } - } public static bool IsValidateAttribute([NotNullWhen(returnValue: true)] this INamedTypeSymbol? typeSymbol) => typeSymbol is diff --git a/src/Immediate.Validations.Analyzers/UnusedConstructorParameterSuppressor.cs b/src/Immediate.Validations.Analyzers/UnusedConstructorParameterSuppressor.cs index 0665920..2817687 100644 --- a/src/Immediate.Validations.Analyzers/UnusedConstructorParameterSuppressor.cs +++ b/src/Immediate.Validations.Analyzers/UnusedConstructorParameterSuppressor.cs @@ -36,7 +36,8 @@ public override void ReportSuppressions(SuppressionAnalysisContext context) if (symbol.BaseType.IsValidatorAttribute()) { - var suppression = SupportedSuppressions.First(s => s.SuppressedDiagnosticId == diagnostic.Id); + var suppression = SupportedSuppressions + .First(s => string.Equals(s.SuppressedDiagnosticId, diagnostic.Id, StringComparison.Ordinal)); context.ReportSuppression( Suppression.Create( diff --git a/src/Immediate.Validations.Analyzers/ValidateClassAnalyzer.cs b/src/Immediate.Validations.Analyzers/ValidateClassAnalyzer.cs index 87f7484..b24ea41 100644 --- a/src/Immediate.Validations.Analyzers/ValidateClassAnalyzer.cs +++ b/src/Immediate.Validations.Analyzers/ValidateClassAnalyzer.cs @@ -352,7 +352,9 @@ ITypeSymbol typeArgumentType attributeProperties ??= attribute.AttributeClass!.GetMembers() .OfType() .ToList(); - var property = attributeProperties.First(a => a.Name == name); + + var property = attributeProperties + .First(a => string.Equals(a.Name, name, StringComparison.Ordinal)); ValidateArgument( context, @@ -370,7 +372,7 @@ ITypeSymbol typeArgumentType { for (var j = 0; j < attributeParameters.Length; j++) { - if (attributeParameters[j].Name == name) + if (string.Equals(attributeParameters[j].Name, name, StringComparison.Ordinal)) { ValidateArgument( context, @@ -422,12 +424,13 @@ List members if (!parameter.IsTargetTypeSymbol()) return; - var validateParameter = validateParameterSymbols.First(p => p.Name == parameter.Name); + var validateParameter = validateParameterSymbols + .First(p => string.Equals(p.Name, parameter.Name, StringComparison.Ordinal)); if (syntax.Expression.IsNameOfExpression(out var propertyName)) { var member = members - .FirstOrDefault(p => p.Name == propertyName); + .Find(p => string.Equals(p.Name, propertyName, StringComparison.Ordinal)); if (member is null) { diff --git a/src/Immediate.Validations.Analyzers/ValidatorClassAnalyzer.cs b/src/Immediate.Validations.Analyzers/ValidatorClassAnalyzer.cs index 6f23240..a44ea9f 100644 --- a/src/Immediate.Validations.Analyzers/ValidatorClassAnalyzer.cs +++ b/src/Immediate.Validations.Analyzers/ValidatorClassAnalyzer.cs @@ -283,8 +283,7 @@ IMethodSymbol methodSymbol .GetMembers() .OfType() .Where(p => - p.Name != "Message" - && !p.IsStatic + p is { Name: not "Message", IsStatic: false } ) .Cast() .ToList(); diff --git a/src/Immediate.Validations.CodeFixes/AddAdditionalValidationsCodeRefactoringProvider.cs b/src/Immediate.Validations.CodeFixes/AddAdditionalValidationsCodeRefactoringProvider.cs index e53b13e..02362ac 100644 --- a/src/Immediate.Validations.CodeFixes/AddAdditionalValidationsCodeRefactoringProvider.cs +++ b/src/Immediate.Validations.CodeFixes/AddAdditionalValidationsCodeRefactoringProvider.cs @@ -9,7 +9,7 @@ namespace Immediate.Validations.CodeFixes; [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = "Add AdditionalValidations Method")] -public class AddAdditionalValidationsCodeRefactoringProvider : CodeRefactoringProvider +public sealed class AddAdditionalValidationsCodeRefactoringProvider : CodeRefactoringProvider { public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { diff --git a/src/Immediate.Validations.CodeFixes/AddValidateMethodCodefixProvider.cs b/src/Immediate.Validations.CodeFixes/AddValidateMethodCodefixProvider.cs index 03a5c75..bc8ed6b 100644 --- a/src/Immediate.Validations.CodeFixes/AddValidateMethodCodefixProvider.cs +++ b/src/Immediate.Validations.CodeFixes/AddValidateMethodCodefixProvider.cs @@ -11,7 +11,7 @@ namespace Immediate.Validations.CodeFixes; [ExportCodeFixProvider(LanguageNames.CSharp)] -public class AddValidateMethodCodefixProvider : CodeFixProvider +public sealed class AddValidateMethodCodefixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create([DiagnosticIds.IV0001ValidateMethodMustExist]); diff --git a/src/Immediate.Validations.CodeFixes/CorrectValidatePropertyReturnTypeCodefixProvider.cs b/src/Immediate.Validations.CodeFixes/CorrectValidatePropertyReturnTypeCodefixProvider.cs index 3d08c27..0c482e0 100644 --- a/src/Immediate.Validations.CodeFixes/CorrectValidatePropertyReturnTypeCodefixProvider.cs +++ b/src/Immediate.Validations.CodeFixes/CorrectValidatePropertyReturnTypeCodefixProvider.cs @@ -10,7 +10,7 @@ namespace Immediate.Validations.CodeFixes; [ExportCodeFixProvider(LanguageNames.CSharp)] -public class CorrectValidatePropertyReturnTypeCodefixProvider : CodeFixProvider +public sealed class CorrectValidatePropertyReturnTypeCodefixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create([DiagnosticIds.IV0004ValidateMethodMustReturnValueTuple]); diff --git a/src/Immediate.Validations.CodeFixes/MakeValidatePropertyMethodStaticCodefixProvider.cs b/src/Immediate.Validations.CodeFixes/MakeValidatePropertyMethodStaticCodefixProvider.cs index d5a651e..4df2d9e 100644 --- a/src/Immediate.Validations.CodeFixes/MakeValidatePropertyMethodStaticCodefixProvider.cs +++ b/src/Immediate.Validations.CodeFixes/MakeValidatePropertyMethodStaticCodefixProvider.cs @@ -9,7 +9,7 @@ namespace Immediate.Validations.CodeFixes; [ExportCodeFixProvider(LanguageNames.CSharp)] -public class MakeValidatePropertyMethodStaticCodefixProvider : CodeFixProvider +public sealed class MakeValidatePropertyMethodStaticCodefixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create([DiagnosticIds.IV0002ValidateMethodMustBeStatic]); diff --git a/src/Immediate.Validations.Generators/Utility.cs b/src/Immediate.Validations.Generators/Utility.cs index 6d2f6a7..3cbfa8a 100644 --- a/src/Immediate.Validations.Generators/Utility.cs +++ b/src/Immediate.Validations.Generators/Utility.cs @@ -18,7 +18,12 @@ public static Template GetTemplate(string name) return Template.Parse(reader.ReadToEnd()); } - private static readonly Regex s_toTitleCaseRegex = new(@"(?<=[^A-Z])([A-Z])"); + private static readonly Regex s_toTitleCaseRegex = + new( + @"(?<=[^A-Z])([A-Z])", + RegexOptions.Compiled, + matchTimeout: TimeSpan.FromMilliseconds(10) + ); public static string ToTitleCase(this string pascalCase) => s_toTitleCaseRegex diff --git a/src/Immediate.Validations.Generators/ValidateTargetTransformer.cs b/src/Immediate.Validations.Generators/ValidateTargetTransformer.cs index 637eccd..695024a 100644 --- a/src/Immediate.Validations.Generators/ValidateTargetTransformer.cs +++ b/src/Immediate.Validations.Generators/ValidateTargetTransformer.cs @@ -194,7 +194,7 @@ ImmutableArray attributes var validateMessage = attributes .FirstOrDefault(a => a.AttributeClass.IsNotNullAttribute()) ?.NamedArguments - .FirstOrDefault(a => a.Key == "Message") is { Value: { Value: { } } value } + .FirstOrDefault(a => a.Key is "Message") is { Value: { Value: { } } value } ? value.ToCSharpString() : null; @@ -424,7 +424,8 @@ ITypeSymbol propertyType attributeProperties ??= attribute.AttributeClass!.GetMembers() .OfType() .ToList(); - var property = attributeProperties.First(a => a.Name == name); + var property = attributeProperties + .First(a => string.Equals(a.Name, name, StringComparison.Ordinal)); var parameterValue = BuildArgumentValue( syntax, @@ -441,7 +442,7 @@ ITypeSymbol propertyType { for (var j = 0; j < attributeParameters.Length; j++) { - if (attributeParameters[j].Name == name) + if (string.Equals(attributeParameters[j].Name, name, StringComparison.Ordinal)) { var parameterValue = BuildArgumentValue( syntax, diff --git a/src/Immediate.Validations.Shared/ExpressionEvaluator.cs b/src/Immediate.Validations.Shared/ExpressionEvaluator.cs index 94422a7..a47fa38 100644 --- a/src/Immediate.Validations.Shared/ExpressionEvaluator.cs +++ b/src/Immediate.Validations.Shared/ExpressionEvaluator.cs @@ -19,7 +19,7 @@ internal static class ExpressionEvaluator NewArrayExpression nae => GetValueFromNewArray(nae), UnaryExpression ue => GetValueFromUnary(ue), null => null, - _ => throw new NotSupportedException(/* TODO: Error Message */), + _ => throw new NotSupportedException("Unknown ExpressionType. Report an issue on the Immediate.Validations repository."), }; [SuppressMessage( @@ -35,7 +35,7 @@ internal static class ExpressionEvaluator null, parameters: [ GetValue(be.Left), - GetValue(be.Right) + GetValue(be.Right), ] ); } diff --git a/src/Immediate.Validations.Shared/Localization/LocalizationDictionary.cs b/src/Immediate.Validations.Shared/Localization/LocalizationDictionary.cs index b4643a8..b0dbe88 100644 --- a/src/Immediate.Validations.Shared/Localization/LocalizationDictionary.cs +++ b/src/Immediate.Validations.Shared/Localization/LocalizationDictionary.cs @@ -1,6 +1,10 @@ -using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Localization; namespace Immediate.Validations.Shared.Localization; internal sealed class LocalizationDictionary(Dictionary localizations) - : Dictionary(localizations.ToDictionary(x => x.Key, x => new LocalizedString(x.Key, x.Value))); + : Dictionary( + localizations + .Select(kvp => KeyValuePair.Create(kvp.Key, new LocalizedString(kvp.Key, kvp.Value))), + StringComparer.Ordinal + ); diff --git a/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.cs b/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.cs index fa12484..71bafa3 100644 --- a/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.cs +++ b/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.cs @@ -5,11 +5,12 @@ namespace Immediate.Validations.Shared.Localization; internal sealed partial class ValidatorLocalizer : IStringLocalizer { - private static readonly Dictionary> s_localizations = new() - { - ["en"] = En(), - ["fr"] = Fr(), - }; + private static readonly Dictionary> s_localizations = + new(StringComparer.Ordinal) + { + ["en"] = En(), + ["fr"] = Fr(), + }; public IEnumerable GetAllStrings(bool includeParentCultures) { @@ -29,7 +30,7 @@ public LocalizedString this[string name] if (s_localizations[currentCulture].TryGetValue(name, out var value)) return value; - return new LocalizedString(name, name, true); + return new LocalizedString(name, name, resourceNotFound: true); } } diff --git a/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.en.cs b/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.en.cs index 202b803..33cacbd 100644 --- a/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.en.cs +++ b/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.en.cs @@ -7,7 +7,7 @@ internal sealed partial class ValidatorLocalizer : IStringLocalizer { [ExcludeFromCodeCoverage] private static Dictionary En() => - new LocalizationDictionary(new() + new LocalizationDictionary(new(StringComparer.Ordinal) { [nameof(EmptyAttribute)] = "'{PropertyName}' must be empty.", [nameof(EnumValueAttribute)] = "'{PropertyName}' has a range of values which does not include '{PropertyValue}'.", diff --git a/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.fr.cs b/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.fr.cs index 161a4fc..49bf942 100644 --- a/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.fr.cs +++ b/src/Immediate.Validations.Shared/Localization/ValidatorLocalizer.fr.cs @@ -7,7 +7,7 @@ internal sealed partial class ValidatorLocalizer : IStringLocalizer { [ExcludeFromCodeCoverage] private static Dictionary Fr() => - new LocalizationDictionary(new() + new LocalizationDictionary(new(StringComparer.Ordinal) { [nameof(EmptyAttribute)] = "'{PropertyName}' doit être vide.", [nameof(EnumValueAttribute)] = "'{PropertyName}' a une plage de valeurs qui n'inclut pas '{PropertyValue}'.", diff --git a/src/Immediate.Validations.Shared/ValidationResult.cs b/src/Immediate.Validations.Shared/ValidationResult.cs index a9657bf..7d6e3d0 100644 --- a/src/Immediate.Validations.Shared/ValidationResult.cs +++ b/src/Immediate.Validations.Shared/ValidationResult.cs @@ -13,7 +13,7 @@ namespace Immediate.Validations.Shared; /// public sealed partial class ValidationResult : IEnumerable { - [GeneratedRegex("{([^{}:]+)(?::([^{}]+))?}")] + [GeneratedRegex("{([^{}:]+)(?::([^{}]+))?}", RegexOptions.None, matchTimeoutMilliseconds: 50)] private static partial Regex FormatRegex(); private List? _errors; @@ -81,6 +81,7 @@ IEnumerable errors /// /// The values which can be used with to build the final validation message. /// + [SuppressMessage("Design", "MA0016:Prefer using collection abstraction instead of implementation")] public void Add( string propertyName, string messageTemplate, @@ -162,7 +163,7 @@ public void Add( var message = overrideMessage ?? GetValidationMessage(method.DeclaringType); - var arguments = new Dictionary + var arguments = new Dictionary(StringComparer.OrdinalIgnoreCase) { ["PropertyValue"] = argumentValues[0], ["PropertyName"] = GetMemberName(targetPropertyExpression, targetObject), @@ -243,7 +244,7 @@ private enum MemberIndex { None = 0, Member, Index, Method } _ => null, }; - [GeneratedRegex(@"(?<=[^A-Z])([A-Z])")] + [GeneratedRegex(@"(?<=[^A-Z])([A-Z])", RegexOptions.None, matchTimeoutMilliseconds: 10)] private static partial Regex FirstCharInWord(); private static string GetMemberName(MemberInfo member) diff --git a/src/Immediate.Validations.Shared/Validators/EmptyAttribute.cs b/src/Immediate.Validations.Shared/Validators/EmptyAttribute.cs index f1b35c1..fe18929 100644 --- a/src/Immediate.Validations.Shared/Validators/EmptyAttribute.cs +++ b/src/Immediate.Validations.Shared/Validators/EmptyAttribute.cs @@ -30,6 +30,6 @@ internal static bool IsEmpty(T value) => null => true, string s when string.IsNullOrWhiteSpace(s) => true, ICollection { Count: 0 } => true, - _ => EqualityComparer.Default.Equals(value, default) + _ => EqualityComparer.Default.Equals(value, default), }; } diff --git a/src/Immediate.Validations.Shared/Validators/MatchAttribute.cs b/src/Immediate.Validations.Shared/Validators/MatchAttribute.cs index 8cdad66..c4031e0 100644 --- a/src/Immediate.Validations.Shared/Validators/MatchAttribute.cs +++ b/src/Immediate.Validations.Shared/Validators/MatchAttribute.cs @@ -42,13 +42,14 @@ public static bool ValidateProperty(string target, Regex? regex = null, [StringS if (expr is null) ThrowInvalidArgumentsException(); - regex = new Regex(expr); + regex = new Regex(expr, RegexOptions.None, TimeSpan.FromMilliseconds(100)); } return regex.IsMatch(target); } [DoesNotReturn] + [SuppressMessage("Usage", "MA0015:Specify the parameter name in ArgumentException", Justification = "Argument Exception applies to multiple properties")] private static void ThrowInvalidArgumentsException() => throw new ArgumentException("Both `regex` and `expr` are `null`. At least one must be provided."); diff --git a/tests/Immediate.Validations.FunctionalTests/.editorconfig b/tests/Immediate.Validations.FunctionalTests/.editorconfig index 1d4f89b..88a91e0 100644 --- a/tests/Immediate.Validations.FunctionalTests/.editorconfig +++ b/tests/Immediate.Validations.FunctionalTests/.editorconfig @@ -1,3 +1,6 @@ [*.cs] dotnet_diagnostic.CA1822.severity = none # CA1822: Mark members as static + +dotnet_diagnostic.MA0009.severity = none +dotnet_diagnostic.MA0016.severity = none diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/CollectionTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/CollectionTests.cs index e63a6ca..85cc0e5 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/CollectionTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/CollectionTests.cs @@ -40,7 +40,7 @@ public void InvalidRecordNullProperty() { PropertyName = "Strings", ErrorMessage = "'Strings' must not be null.", - } + }, ], errors ); @@ -158,7 +158,7 @@ public void InvalidCommandNullProperty() { PropertyName = "Commands", ErrorMessage = "'Commands' must not be null.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/DuplicateTypeVisitTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/DuplicateTypeVisitTests.cs index d0f39ff..a146a6b 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/DuplicateTypeVisitTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/DuplicateTypeVisitTests.cs @@ -2,7 +2,7 @@ namespace Immediate.Validations.FunctionalTests.IntegrationTests; -public partial class DuplicateTypeVisitTests +public sealed partial class DuplicateTypeVisitTests { [Validate] public partial interface IBaseInterface : IValidationTarget diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/InheritanceTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/InheritanceTests.cs index acd99ac..cc05092 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/InheritanceTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/InheritanceTests.cs @@ -55,7 +55,7 @@ public void ShortIdHasErrors() { PropertyName = "Id", ErrorMessage = "'Id' must be more than 4 characters.", - } + }, ], errors ); @@ -78,7 +78,7 @@ public void EmptyDescriptionHasErrors() { PropertyName = "Description", ErrorMessage = "'Description' must not be empty.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/SkipSelfTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/SkipSelfTests.cs index 6ee8ec5..fa711dc 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/SkipSelfTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/SkipSelfTests.cs @@ -29,7 +29,7 @@ public void SkipSelfOperatesCorrectly() { PropertyName = nameof(BaseClass.BaseString), ErrorMessage = "'Base String' must not be null.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/StructTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/StructTests.cs index de3aebe..f85458c 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/StructTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/StructTests.cs @@ -39,7 +39,7 @@ public void InvalidRecordStructNullProperty() { PropertyName = "StringProperty", ErrorMessage = "'String Property' must not be null.", - } + }, ], errors ); @@ -68,7 +68,7 @@ public void InvalidStructNullProperty() { PropertyName = "StringProperty", ErrorMessage = "'String Property' must not be null.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidationResultTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidationResultTests.cs index 258c98e..f7c7d0e 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidationResultTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidationResultTests.cs @@ -276,7 +276,7 @@ public void PropertyNameTest1() { PropertyName = "Value", ErrorMessage = "'Value' must be empty.", - } + }, ], results ); @@ -300,7 +300,7 @@ public void PropertyNameTest2() { PropertyName = "HelloWorld", ErrorMessage = "'Hello World' must be empty.", - } + }, ], results ); @@ -341,7 +341,7 @@ public void PropertyNameTest3() { PropertyName = "SomeArray[0]", ErrorMessage = "'Some Array[0]' must be empty.", - } + }, ], results ); @@ -365,7 +365,7 @@ public void PropertyNameTest4() { PropertyName = "SomeList[0]", ErrorMessage = "'Some List[0]' must be empty.", - } + }, ], results ); @@ -389,7 +389,7 @@ public void PropertyNameTest5() { PropertyName = "SomeDictionary[123]", ErrorMessage = "'Some Dictionary[123]' must be empty.", - } + }, ], results ); @@ -415,7 +415,7 @@ public void PropertyNameTest6() { PropertyName = "Value", ErrorMessage = "'DoSomethingInstance()'", - } + }, ], results ); @@ -441,7 +441,7 @@ public void PropertyNameTest7() { PropertyName = "HelloWorld", ErrorMessage = "'DoSomething()'", - } + }, ], results ); @@ -467,7 +467,7 @@ public void PropertyNameTest8() { PropertyName = "Value", ErrorMessage = "'Max Value'", - } + }, ], results ); diff --git a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidatorLocalizerTests.cs b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidatorLocalizerTests.cs index c97d4b1..d4ae3dd 100644 --- a/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidatorLocalizerTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/IntegrationTests/ValidatorLocalizerTests.cs @@ -1,10 +1,10 @@ -using System.Globalization; +using System.Globalization; using Immediate.Validations.Shared; using Immediate.Validations.Shared.Localization; namespace Immediate.Validations.FunctionalTests.IntegrationTests; -public class ValidatorLocalizerTests +public sealed class ValidatorLocalizerTests { [Test] public void GetAllStringsReturnsCorrectLocalizationsForCurrentCulture() @@ -12,11 +12,14 @@ public void GetAllStringsReturnsCorrectLocalizationsForCurrentCulture() var localizer = new ValidatorLocalizer(); CultureInfo.CurrentUICulture = new CultureInfo("en"); - var strings = localizer.GetAllStrings(false).ToList(); + var strings = localizer.GetAllStrings(includeParentCultures: false).ToList(); Assert.NotNull(strings); Assert.Equal(15, strings.Count); - Assert.Contains(strings, s => s.Name == nameof(EmptyAttribute) && s.Value == "'{PropertyName}' must be empty."); + Assert.Contains( + strings, + s => string.Equals(s.Name, nameof(EmptyAttribute), StringComparison.Ordinal) + && string.Equals(s.Value, "'{PropertyName}' must be empty.", StringComparison.Ordinal)); } [Test] diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/EmptyTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/EmptyTests.cs index e0274da..cee559b 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/EmptyTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/EmptyTests.cs @@ -48,7 +48,7 @@ public void StringEmptyTestWhenNotEmpty() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must be empty.", - } + }, ], errors ); @@ -77,7 +77,7 @@ public void IntEmptyTestWhenNotEmpty() { PropertyName = nameof(IntRecord.IntValue), ErrorMessage = "'Int Value' must be empty.", - } + }, ], errors ); @@ -106,7 +106,7 @@ public void CollectionEmptyTestWhenNotEmpty() { PropertyName = nameof(CollectionRecord.CollectionValue), ErrorMessage = "'Collection Value' must be empty.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/EnumValueTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/EnumValueTests.cs index dce69ca..74b558b 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/EnumValueTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/EnumValueTests.cs @@ -54,7 +54,7 @@ public void EnumInvalidValue() { PropertyName = nameof(EnumRecord.ValidState), ErrorMessage = "'Valid State' has a range of values which does not include '3'.", - } + }, ], errors ); @@ -93,7 +93,7 @@ public void FlagsEnumInvalidValue() { PropertyName = nameof(EnumRecord.ValidState), ErrorMessage = "'Valid State' has a range of values which does not include '4'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/EqualTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/EqualTests.cs index c04273c..73951f0 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/EqualTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/EqualTests.cs @@ -42,7 +42,7 @@ public void IntEqualRecordWhenNotZero() { PropertyName = nameof(IntEqualRecord.IntValue), ErrorMessage = "'Int Value' must be equal to '0'.", - } + }, ], errors ); @@ -71,7 +71,7 @@ public void StringEqualRecordWhenNotEqual() { PropertyName = nameof(StringEqualRecord.StringValue), ErrorMessage = "'String Value' must be equal to 'Test'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanOrEqualTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanOrEqualTests.cs index 623538d..6ba2312 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanOrEqualTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanOrEqualTests.cs @@ -42,7 +42,7 @@ public void IntGreaterThanRecordWhenNotZero() { PropertyName = nameof(IntGreaterThanRecord.IntValue), ErrorMessage = "'Int Value' must be greater than or equal to '0'.", - } + }, ], errors ); @@ -71,7 +71,7 @@ public void StringGreaterThanRecordWhenNotGreaterThan() { PropertyName = nameof(StringGreaterThanRecord.StringValue), ErrorMessage = "'String Value' must be greater than or equal to 'Foo'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanTests.cs index 3d42c0b..1c54c70 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/GreaterThanTests.cs @@ -42,7 +42,7 @@ public void IntGreaterThanRecordWhenNotZero() { PropertyName = nameof(IntGreaterThanRecord.IntValue), ErrorMessage = "'Int Value' must be greater than '0'.", - } + }, ], errors ); @@ -71,7 +71,7 @@ public void StringGreaterThanRecordWhenNotGreaterThan() { PropertyName = nameof(StringGreaterThanRecord.StringValue), ErrorMessage = "'String Value' must be greater than 'Foo'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/LengthTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/LengthTests.cs index 55f62f1..54f584b 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/LengthTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/LengthTests.cs @@ -24,7 +24,7 @@ public void LengthWhenShort() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must be between 12 and 12 characters.", - } + }, ], errors ); @@ -53,7 +53,7 @@ public void LengthWhenLong() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must be between 12 and 12 characters.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/LessThanOrEqualTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/LessThanOrEqualTests.cs index a7291fc..51df96f 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/LessThanOrEqualTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/LessThanOrEqualTests.cs @@ -42,7 +42,7 @@ public void IntLessThanRecordWhenNotZero() { PropertyName = nameof(IntLessThanRecord.IntValue), ErrorMessage = "'Int Value' must be less than or equal to '0'.", - } + }, ], errors ); @@ -71,7 +71,7 @@ public void StringLessThanRecordWhenNotLessThan() { PropertyName = nameof(StringLessThanRecord.StringValue), ErrorMessage = "'String Value' must be less than or equal to 'Foo'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/LessThanTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/LessThanTests.cs index 99bf95f..8a7e9b7 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/LessThanTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/LessThanTests.cs @@ -42,7 +42,7 @@ public void IntLessThanRecordWhenNotZero() { PropertyName = nameof(IntLessThanRecord.IntValue), ErrorMessage = "'Int Value' must be less than '0'.", - } + }, ], errors ); @@ -71,7 +71,7 @@ public void StringLessThanRecordWhenNotLessThan() { PropertyName = nameof(StringLessThanRecord.StringValue), ErrorMessage = "'String Value' must be less than 'Foo'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/MaxLengthTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/MaxLengthTests.cs index 4297395..965bd34 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/MaxLengthTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/MaxLengthTests.cs @@ -34,7 +34,7 @@ public void MaxLengthWhenLong() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must be less than 30 characters.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/MinLengthTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/MinLengthTests.cs index 8e2b026..2b26ae6 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/MinLengthTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/MinLengthTests.cs @@ -34,7 +34,7 @@ public void MinLengthWhenLong() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must be more than 30 characters.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/NotEmptyTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/NotEmptyTests.cs index 8510d02..555f0e7 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/NotEmptyTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/NotEmptyTests.cs @@ -48,7 +48,7 @@ public void StringNotEmptyTestWhenEmpty() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must not be empty.", - } + }, ], errors ); @@ -77,7 +77,7 @@ public void IntNotEmptyTestWhenEmpty() { PropertyName = nameof(IntRecord.IntValue), ErrorMessage = "'Int Value' must not be empty.", - } + }, ], errors ); @@ -106,7 +106,7 @@ public void CollectionNotEmptyTestWhenEmpty() { PropertyName = nameof(CollectionRecord.CollectionValue), ErrorMessage = "'Collection Value' must not be empty.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/NotEqualTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/NotEqualTests.cs index 897db24..3d19d1e 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/NotEqualTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/NotEqualTests.cs @@ -42,7 +42,7 @@ public void IntEqualRecordWhenNotZero() { PropertyName = nameof(IntEqualRecord.IntValue), ErrorMessage = "'Int Value' must not be equal to '0'.", - } + }, ], errors ); @@ -71,7 +71,7 @@ public void StringEqualRecordWhenNotEqual() { PropertyName = nameof(StringEqualRecord.StringValue), ErrorMessage = "'String Value' must not be equal to 'Test'.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/NotNullTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/NotNullTests.cs index c447b41..9f1d975 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/NotNullTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/NotNullTests.cs @@ -41,7 +41,7 @@ public void StringNotNullTestWhenNull() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' must not be null.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.FunctionalTests/Validators/OneOfTests.cs b/tests/Immediate.Validations.FunctionalTests/Validators/OneOfTests.cs index 3ec53c7..7dde2f1 100644 --- a/tests/Immediate.Validations.FunctionalTests/Validators/OneOfTests.cs +++ b/tests/Immediate.Validations.FunctionalTests/Validators/OneOfTests.cs @@ -65,7 +65,7 @@ public void StringValueIsNotOneOfHasErrors() { PropertyName = nameof(StringRecord.StringValue), ErrorMessage = "'String Value' was not one of the specified values: 123, 456, 789.", - } + }, ], errors ); @@ -94,7 +94,7 @@ public void IntValueIsNotOneOfHasErrors() { PropertyName = nameof(IntRecord.IntValue), ErrorMessage = "'Int Value' was not one of the specified values: 123, 456, 789.", - } + }, ], errors ); @@ -123,7 +123,7 @@ public void IntFieldValueIsNotOneOfHasErrors() { PropertyName = nameof(IntFieldRecord.IntValue), ErrorMessage = "'Int Value' was not one of the specified values: 123, 456, 789.", - } + }, ], errors ); @@ -152,7 +152,7 @@ public void EnumValueIsNotOneOfHasErrors() { PropertyName = nameof(EnumRecord.EnumValue), ErrorMessage = "'Enum Value' was not one of the specified values: Value1, Value2.", - } + }, ], errors ); diff --git a/tests/Immediate.Validations.Tests/CodeFixTests/CodeFixTestHelper.cs b/tests/Immediate.Validations.Tests/CodeFixTests/CodeFixTestHelper.cs index b5e23a4..b53f3ce 100644 --- a/tests/Immediate.Validations.Tests/CodeFixTests/CodeFixTestHelper.cs +++ b/tests/Immediate.Validations.Tests/CodeFixTests/CodeFixTestHelper.cs @@ -39,9 +39,9 @@ public static CSharpCodeFixTest CreateCode new PackageIdentity( "Microsoft.NETCore.App.Ref", "8.0.0"), - Path.Combine("ref", "net8.0")) + Path.Combine("ref", "net8.0")), }, - FixedState = { MarkupHandling = MarkupMode.IgnoreFixable, Sources = { fixedSource } } + FixedState = { MarkupHandling = MarkupMode.IgnoreFixable, Sources = { fixedSource } }, }; csTest.TestState.AdditionalReferences diff --git a/tests/Immediate.Validations.Tests/CodeFixTests/CodeRefactoringTestHelper.cs b/tests/Immediate.Validations.Tests/CodeFixTests/CodeRefactoringTestHelper.cs index 38e1107..82d05c8 100644 --- a/tests/Immediate.Validations.Tests/CodeFixTests/CodeRefactoringTestHelper.cs +++ b/tests/Immediate.Validations.Tests/CodeFixTests/CodeRefactoringTestHelper.cs @@ -36,9 +36,9 @@ public static CSharpCodeRefactoringTest CreateCod new PackageIdentity( "Microsoft.NETCore.App.Ref", "8.0.0"), - Path.Combine("ref", "net8.0")) + Path.Combine("ref", "net8.0")), }, - FixedState = { MarkupHandling = MarkupMode.IgnoreFixable, Sources = { fixedSource } } + FixedState = { MarkupHandling = MarkupMode.IgnoreFixable, Sources = { fixedSource } }, }; csTest.TestState.AdditionalReferences