diff --git a/Px.Utils.TestingApp/Commands/DatabaseValidationBenchmark.cs b/Px.Utils.TestingApp/Commands/DatabaseValidationBenchmark.cs index c9d09cb..b060048 100644 --- a/Px.Utils.TestingApp/Commands/DatabaseValidationBenchmark.cs +++ b/Px.Utils.TestingApp/Commands/DatabaseValidationBenchmark.cs @@ -2,7 +2,7 @@ namespace Px.Utils.TestingApp.Commands { - internal class DatabaseValidationBenchmark : Benchmark + internal sealed class DatabaseValidationBenchmark : Benchmark { internal override string Help => "Validates a px path database."; @@ -56,12 +56,12 @@ protected override void OneTimeBenchmarkSetup() validator = new(TestFilePath); } - protected void ValidationBenchmark() + private void ValidationBenchmark() { validator.Validate(); } - protected async Task ValidationBenchmarkAsync() + private async Task ValidationBenchmarkAsync() { await validator.ValidateAsync(); } diff --git a/Px.Utils.TestingApp/Commands/MetadataSyntaxValidationBenchmark.cs b/Px.Utils.TestingApp/Commands/MetadataSyntaxValidationBenchmark.cs index 66f7094..a680511 100644 --- a/Px.Utils.TestingApp/Commands/MetadataSyntaxValidationBenchmark.cs +++ b/Px.Utils.TestingApp/Commands/MetadataSyntaxValidationBenchmark.cs @@ -13,9 +13,7 @@ internal sealed class MetadataSyntaxValidationBenchmark : FileBenchmark internal override string Description => "Benchmarks the metadata syntax validation of Px.Utils/Validation/SyntaxValidator."; - private Encoding encoding; private SyntaxValidator validator; - private Stream stream; internal MetadataSyntaxValidationBenchmark() { @@ -29,7 +27,7 @@ protected override void OneTimeBenchmarkSetup() Stream stream = new FileStream(TestFilePath, FileMode.Open, FileAccess.Read); PxFileMetadataReader reader = new(); - encoding = reader.GetEncoding(stream); + Encoding encoding = reader.GetEncoding(stream); validator = new(stream, encoding, TestFilePath, leaveStreamOpen: true); } diff --git a/Px.Utils.TestingApp/Commands/PxFileValidationBenchmark.cs b/Px.Utils.TestingApp/Commands/PxFileValidationBenchmark.cs index ab61bff..49ce752 100644 --- a/Px.Utils.TestingApp/Commands/PxFileValidationBenchmark.cs +++ b/Px.Utils.TestingApp/Commands/PxFileValidationBenchmark.cs @@ -4,7 +4,7 @@ namespace Px.Utils.TestingApp.Commands { - internal class PxFileValidationBenchmark : FileBenchmark + internal sealed class PxFileValidationBenchmark : FileBenchmark { internal override string Help => "Runs through the whole px file validation process (metadata syntax- and contents-, data-) for the given file."; diff --git a/Px.Utils.UnitTests/Validation/ContentValidationTests/ContentValidationTests.cs b/Px.Utils.UnitTests/Validation/ContentValidationTests/ContentValidationTests.cs index 00acab2..2bc90d2 100644 --- a/Px.Utils.UnitTests/Validation/ContentValidationTests/ContentValidationTests.cs +++ b/Px.Utils.UnitTests/Validation/ContentValidationTests/ContentValidationTests.cs @@ -1,5 +1,4 @@ -using Px.Utils.PxFile; -using Px.Utils.UnitTests.Validation.Fixtures; +using Px.Utils.UnitTests.Validation.Fixtures; using Px.Utils.Validation; using Px.Utils.Validation.ContentValidation; using Px.Utils.Validation.SyntaxValidation; @@ -41,10 +40,10 @@ public void ValidatePxFileContentCalledWithMinimalStructuredEntryReturnsValidRes ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[] feedback = validator.Validate().FeedbackItems; + ContentValidationResult feedback = validator.Validate(); // Assert - Assert.AreEqual(0, feedback.Length); + Assert.AreEqual(0, feedback.FeedbackItems.Count); } [TestMethod] @@ -55,15 +54,15 @@ public void ValidateFindDefaultLanguageWithEmptyStructuredEntryArrayReturnsWithE ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindDefaultLanguage( + ValidationFeedback? result = ContentValidator.ValidateFindDefaultLanguage( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.MissingDefaultLanguage, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.MissingDefaultLanguage, result.First().Key.Rule); } [TestMethod] @@ -74,15 +73,15 @@ public void ValidateFindAvailableLanguagesWithEmptyStructuredArrayReturnsWithWar ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindAvailableLanguages( + ValidationFeedback? result = ContentValidator.ValidateFindAvailableLanguages( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result.First().Key.Rule); } [TestMethod] @@ -95,15 +94,15 @@ public void ValidateDefaultLanguageDefinedInAvailableLanguagesCalledWithUndefine SetValidatorField(validator, "_availableLanguages", availableLanguages); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateDefaultLanguageDefinedInAvailableLanguages( + ValidationFeedback? result = ContentValidator.ValidateDefaultLanguageDefinedInAvailableLanguages( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.UndefinedLanguageFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.UndefinedLanguageFound, result.First().Key.Rule); } [TestMethod] @@ -116,15 +115,15 @@ public void ValidateFindContentDimensionCalledWithMissingContVariableReturnsWith SetValidatorField(validator, "_availableLanguages", availableLanguages); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindContentDimension( + ValidationFeedback? result = ContentValidator.ValidateFindContentDimension( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result.First().Key.Rule); } [TestMethod] @@ -135,17 +134,16 @@ public void ValidateFindRequiredCommonKeysCalledWithEmptyStructuredEntryArrayYRe ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindRequiredCommonKeys( + ValidationFeedback? result = ContentValidator.ValidateFindRequiredCommonKeys( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(3, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result[2].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(3, result.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result.First().Key.Rule); } [TestMethod] @@ -158,14 +156,14 @@ public void ValidateFindStubOrHeadingCalledWithListsOfNamesReturnWithNoErrors() SetValidatorField(validator, "_availableLanguages", availableLanguages); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindStubAndHeading( + ValidationFeedback? result = ContentValidator.ValidateFindStubAndHeading( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(0, result.Length); + Assert.AreEqual(0, result.Count); } [TestMethod] @@ -178,15 +176,15 @@ public void ValidateFindStubOrHeadingCalledWithWithMissingHeadingReturnsWithErro SetValidatorField(validator, "_availableLanguages", availableLanguages); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindStubAndHeading( + ValidationFeedback? result = ContentValidator.ValidateFindStubAndHeading( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.MissingStubAndHeading, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.MissingStubAndHeading, result.First().Key.Rule); } [TestMethod] @@ -200,16 +198,16 @@ public void ValidateFindRecommendedKeysCalledWithMissingDescriptionsReturnsWithW SetValidatorField(validator, "_availableLanguages", availableLanguages); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindRecommendedKeys( + ValidationFeedback? result = ContentValidator.ValidateFindRecommendedKeys( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(2, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[1].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(2, result.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result.First().Key.Rule); } [TestMethod] @@ -227,17 +225,16 @@ public void ValidateFindDimenionsValuesCalledWithMissingDimensionValuesReturnsEr }); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindDimensionValues( + ValidationFeedback? result = ContentValidator.ValidateFindDimensionValues( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(3, result.Length); - Assert.AreEqual(ValidationFeedbackRule.VariableValuesMissing, result[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.VariableValuesMissing, result[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.VariableValuesMissing, result[2].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(3, result.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.VariableValuesMissing, result.First().Key.Rule); } [TestMethod] @@ -256,16 +253,16 @@ public void ValidateFindContentDimensionKeysCalledWithMissingContentValueKeyEntr }); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindContentDimensionKeys( + ValidationFeedback? result = ContentValidator.ValidateFindContentDimensionKeys( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(2, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result[1].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(2, result.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.RequiredKeyMissing, result.First().Key.Rule); } [TestMethod] @@ -282,19 +279,22 @@ public void ValidateFindContentDimensionKeysCalledWithMissingRecommendedSpecifie { new KeyValuePair( "fi", "bar" ), ["foo"] }, { new KeyValuePair( "en", "bar-en" ), ["foo-en"] }, }); + ValidationFeedbackKey recommendedKeyFeedbackKey = new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.RecommendedKeyMissing); + ValidationFeedbackKey recommendedSpecifierFeedbackKey = new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.RecommendedSpecifierDefinitionMissing); + // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindContentDimensionKeys( + ValidationFeedback? result = ContentValidator.ValidateFindContentDimensionKeys( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(3, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RecommendedSpecifierDefinitionMissing, result[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RecommendedSpecifierDefinitionMissing, result[2].Feedback.Rule); + Assert.AreEqual(2, result.Count); + Assert.IsTrue(result.ContainsKey(recommendedKeyFeedbackKey)); + Assert.IsTrue(result.ContainsKey(recommendedSpecifierFeedbackKey)); + Assert.AreEqual(2, result[recommendedSpecifierFeedbackKey].Count); } [TestMethod] @@ -309,18 +309,16 @@ public void ValidateFindDimensionRecommendedKeysCalledWithIncompleteVariableReco SetValidatorField(validator, "_stubDimensionNames", stubDimensionNames); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindDimensionRecommendedKeys( + ValidationFeedback? result = ContentValidator.ValidateFindDimensionRecommendedKeys( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(4, result.Length); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[2].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result[3].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(4, result.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.RecommendedKeyMissing, result.First().Key.Rule); } [TestMethod] @@ -331,15 +329,15 @@ public void ValidateUnexpectedSpecifiersCalledWithStructuredEntryWithIllegalSpec ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateUnexpectedSpecifiers( + ValidationFeedback? result = ContentValidator.ValidateUnexpectedSpecifiers( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.IllegalSpecifierDefinitionFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.IllegalSpecifierDefinitionFound, result.First().Key.Rule); } [TestMethod] @@ -350,15 +348,15 @@ public void ValidateUnexpectedSpecifiersCalledWithStructuredEntryWithIllegalLang ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateUnexpectedLanguageParams( + ValidationFeedback? result = ContentValidator.ValidateUnexpectedLanguageParams( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.IllegalLanguageDefinitionFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.IllegalLanguageDefinitionFound, result.First().Key.Rule); } [TestMethod] @@ -371,15 +369,15 @@ public void ValidateLanguageParamsCalledWithUndefinedLanguageReturnshWithErrors( SetValidatorField(validator, "_availableLanguages", availableLanguages); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateLanguageParams( + ValidationFeedback? result = ContentValidator.ValidateLanguageParams( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.UndefinedLanguageFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.UndefinedLanguageFound, result.First().Key.Rule); } [TestMethod] @@ -394,15 +392,15 @@ public void ValidateSpecifiersCalledWithUndefinedFirstSpecifierReturnsWithErrors SetValidatorField(validator, "_dimensionValueNames", dimensionValueNames); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateSpecifiers( + ValidationFeedback? result = ContentValidator.ValidateSpecifiers( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.IllegalSpecifierDefinitionFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.IllegalSpecifierDefinitionFound, result.First().Key.Rule); } [TestMethod] @@ -417,15 +415,15 @@ public void ValidateSpecifiersCalledWithUndefinedSecondSpecifierReturnsWithError SetValidatorField(validator, "_dimensionValueNames", dimensionValueNames); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateSpecifiers( + ValidationFeedback? result = ContentValidator.ValidateSpecifiers( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.IllegalSpecifierDefinitionFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.IllegalSpecifierDefinitionFound, result.First().Key.Rule); } [TestMethod] @@ -438,15 +436,15 @@ public void ValidateValueTypesCalledWithStructuredEntryArrayWithInvalidValueType // Act foreach (ValidationStructuredEntry entry in entries) { - ValidationFeedbackItem[]? result = ContentValidator.ValidateValueTypes( + ValidationFeedback? result = ContentValidator.ValidateValueTypes( entry, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.UnmatchingValueType, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.UnmatchingValueType, result.First().Key.Rule); } } @@ -460,15 +458,15 @@ public void ValidateValueTypesCalledWithStructuredEntryArrayWithWrongValuesRetur // Act foreach (ValidationStructuredEntry entry in entries) { - ValidationFeedbackItem[]? result = ContentValidator.ValidateValueContents( + ValidationFeedback? result = ContentValidator.ValidateValueContents( entry, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFound, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.InvalidValueFound, result.First().Key.Rule); } } @@ -484,15 +482,15 @@ public void ValidateValueAmountsCalledWithUnmatchingAmountOfElementsReturnsWithE SetValidatorField(validator, "_dimensionValueNames", dimensionValueNames); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateValueAmounts( + ValidationFeedback? result = ContentValidator.ValidateValueAmounts( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.UnmatchingValueAmount, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.UnmatchingValueAmount, result.First().Key.Rule); } [TestMethod] @@ -503,15 +501,15 @@ public void ValidateValueUppercaseRecommendationsCalledWithLowerCaseEntryReturns ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateValueUppercaseRecommendations( + ValidationFeedback? result = ContentValidator.ValidateValueUppercaseRecommendations( entries[0], validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.ValueIsNotInUpperCase, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.ValueIsNotInUpperCase, result.First().Key.Rule); } [TestMethod] @@ -522,10 +520,10 @@ public void ValidateContentWithCustomFunctionsReturnsValidResult() ContentValidator validator = new(filename, encoding, entries, new MockCustomContentValidationFunctions()); // Act - ValidationFeedbackItem[] feedback = validator.Validate().FeedbackItems; + ValidationFeedback feedback = validator.Validate().FeedbackItems; // Assert - Assert.AreEqual(0, feedback.Length); + Assert.AreEqual(0, feedback.Count); } [TestMethod] @@ -536,15 +534,15 @@ public void ValidateFindDefaultWithMultipleDefaultLanguagesReturnsError() ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindDefaultLanguage( + ValidationFeedback? result = ContentValidator.ValidateFindDefaultLanguage( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.MultipleInstancesOfUniqueKey, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.MultipleInstancesOfUniqueKey, result.First().Key.Rule); } [TestMethod] @@ -555,15 +553,15 @@ public void ValidateFindAvailableLanguagesWithMultipleAvailableLanguagesEntriesR ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindAvailableLanguages( + ValidationFeedback? result = ContentValidator.ValidateFindAvailableLanguages( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.MultipleInstancesOfUniqueKey, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.MultipleInstancesOfUniqueKey, result.First().Key.Rule); } [TestMethod] @@ -574,15 +572,15 @@ public void ValidateFindStubAndHeadingWithMissingStubAndHeadingReturnsError() ContentValidator validator = new(filename, encoding, entries); // Act - ValidationFeedbackItem[]? result = ContentValidator.ValidateFindStubAndHeading( + ValidationFeedback? result = ContentValidator.ValidateFindStubAndHeading( entries, validator ); // Assert Assert.IsNotNull(result); - Assert.AreEqual(1, result.Length); - Assert.AreEqual(ValidationFeedbackRule.MissingStubAndHeading, result[0].Feedback.Rule); + Assert.AreEqual(1, result.Count); + Assert.AreEqual(ValidationFeedbackRule.MissingStubAndHeading, result.First().Key.Rule); } private static void SetValidatorField(ContentValidator validator, string fieldName, object value) diff --git a/Px.Utils.UnitTests/Validation/ContentValidationTests/MockCustomContentValidationFunctions.cs b/Px.Utils.UnitTests/Validation/ContentValidationTests/MockCustomContentValidationFunctions.cs index 7ef79e2..8a18eea 100644 --- a/Px.Utils.UnitTests/Validation/ContentValidationTests/MockCustomContentValidationFunctions.cs +++ b/Px.Utils.UnitTests/Validation/ContentValidationTests/MockCustomContentValidationFunctions.cs @@ -6,12 +6,12 @@ namespace Px.Utils.UnitTests.Validation.ContentValidationTests { internal sealed class MockCustomContentValidationFunctions : CustomContentValidationFunctions { - internal static ValidationFeedbackItem[]? MockFindKeywordFunction(ValidationStructuredEntry[] entries, ContentValidator validator) + internal static ValidationFeedback? MockFindKeywordFunction(ValidationStructuredEntry[] entries, ContentValidator validator) { return null; } - internal static ValidationFeedbackItem[]? MockEntryFunction(ValidationStructuredEntry entry, ContentValidator validator) + internal static ValidationFeedback? MockEntryFunction(ValidationStructuredEntry entry, ContentValidator validator) { return null; } diff --git a/Px.Utils.UnitTests/Validation/DataValidationTests/DataNumberValueValidatorTest.cs b/Px.Utils.UnitTests/Validation/DataValidationTests/DataNumberValueValidatorTest.cs index 135e16b..cebf10b 100644 --- a/Px.Utils.UnitTests/Validation/DataValidationTests/DataNumberValueValidatorTest.cs +++ b/Px.Utils.UnitTests/Validation/DataValidationTests/DataNumberValueValidatorTest.cs @@ -25,7 +25,7 @@ public void AllowedNumberValues(string allowedValue) DataNumberValidator validator = new(); Encoding encoding = Encoding.UTF8; List value = [.. encoding.GetBytes(allowedValue)]; - ValidationFeedback? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0); + KeyValuePair? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0, "foo"); Assert.IsNull(nullableFeedback); } @@ -48,13 +48,13 @@ public void NotAllowedNumberValue(string notAllowedValue) Encoding encoding = Encoding.UTF8; List value = [.. encoding.GetBytes(notAllowedValue)]; - ValidationFeedback? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0); + KeyValuePair? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0, "foo"); Assert.IsNotNull(nullableFeedback); - ValidationFeedback feedback = (ValidationFeedback)nullableFeedback; - Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInvalidNumber, feedback.Rule); - Assert.AreEqual(notAllowedValue, feedback.AdditionalInfo); - Assert.AreEqual(ValidationFeedbackLevel.Error, feedback.Level); + KeyValuePair feedback = (KeyValuePair)nullableFeedback; + Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInvalidNumber, feedback.Key.Rule); + Assert.AreEqual(notAllowedValue, feedback.Value.AdditionalInfo); + Assert.AreEqual(ValidationFeedbackLevel.Error, feedback.Key.Level); } diff --git a/Px.Utils.UnitTests/Validation/DataValidationTests/DataSeparatorValidatorTest.cs b/Px.Utils.UnitTests/Validation/DataValidationTests/DataSeparatorValidatorTest.cs index 7c3b223..4820a6d 100644 --- a/Px.Utils.UnitTests/Validation/DataValidationTests/DataSeparatorValidatorTest.cs +++ b/Px.Utils.UnitTests/Validation/DataValidationTests/DataSeparatorValidatorTest.cs @@ -12,7 +12,7 @@ public void FirstSeparatorIsUsedAsReference() { DataSeparatorValidator validator = new(); List separator = [.. Encoding.UTF8.GetBytes(" ")]; - ValidationFeedback? nullableFeedback = validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1); + KeyValuePair? nullableFeedback = validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1, "foo"); Assert.IsNull(nullableFeedback); } @@ -22,14 +22,14 @@ public void InconsistentSeparator() { DataSeparatorValidator validator = new(); List separator = [.. Encoding.UTF8.GetBytes(" ")]; - validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1); + validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1, "foo"); List otherSeparator = [.. Encoding.UTF8.GetBytes("\t")]; - ValidationFeedback? nullableFeedback = validator.Validate(otherSeparator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1); + KeyValuePair? nullableFeedback = validator.Validate(otherSeparator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1, "foo"); Assert.IsNotNull(nullableFeedback); - ValidationFeedback feedback = (ValidationFeedback)nullableFeedback; - Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInconsistentSeparator, feedback.Rule); - Assert.AreEqual(ValidationFeedbackLevel.Warning, feedback.Level); + KeyValuePair feedback = (KeyValuePair)nullableFeedback; + Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInconsistentSeparator, feedback.Key.Rule); + Assert.AreEqual(ValidationFeedbackLevel.Warning, feedback.Key.Level); } @@ -39,8 +39,8 @@ public void ConsistentSeparator() { DataSeparatorValidator validator = new(); List separator = [.. Encoding.UTF8.GetBytes(" ")]; - validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1); - ValidationFeedback? nullableFeedback = validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1); + validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1, "foo"); + KeyValuePair? nullableFeedback = validator.Validate(separator, EntryType.DataItemSeparator, Encoding.UTF8, 1, 1, "foo"); Assert.IsNull(nullableFeedback); } } diff --git a/Px.Utils.UnitTests/Validation/DataValidationTests/DataStringValueValidatorTests.cs b/Px.Utils.UnitTests/Validation/DataValidationTests/DataStringValueValidatorTests.cs index 7515ae5..7c106e9 100644 --- a/Px.Utils.UnitTests/Validation/DataValidationTests/DataStringValueValidatorTests.cs +++ b/Px.Utils.UnitTests/Validation/DataValidationTests/DataStringValueValidatorTests.cs @@ -21,7 +21,7 @@ public void AllowedStrings(string allowedValue) DataStringValidator validator = new(); Encoding encoding = Encoding.UTF8; List value = [.. encoding.GetBytes(allowedValue)]; - ValidationFeedback? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0); + KeyValuePair? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0, "foo"); Assert.IsNull(nullableFeedback); } @@ -43,13 +43,13 @@ public void NotAllowedStringValue(string notAllowedValue) Encoding encoding = Encoding.UTF8; List value = [.. encoding.GetBytes(notAllowedValue)]; - ValidationFeedback? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0); + KeyValuePair? nullableFeedback = validator.Validate(value, EntryType.DataItem, encoding, 0, 0, "foo"); Assert.IsNotNull(nullableFeedback); - ValidationFeedback feedback = (ValidationFeedback)nullableFeedback; - Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInvalidString, feedback.Rule); - Assert.AreEqual(notAllowedValue, feedback.AdditionalInfo); - Assert.AreEqual(ValidationFeedbackLevel.Error, feedback.Level); + KeyValuePair feedback = (KeyValuePair)nullableFeedback; + Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInvalidString, feedback.Key.Rule); + Assert.AreEqual(notAllowedValue, feedback.Value.AdditionalInfo); + Assert.AreEqual(ValidationFeedbackLevel.Error, feedback.Key.Level); } } } \ No newline at end of file diff --git a/Px.Utils.UnitTests/Validation/DataValidationTests/DataStructureValidationTests.cs b/Px.Utils.UnitTests/Validation/DataValidationTests/DataStructureValidationTests.cs index 31728f2..1a45b00 100644 --- a/Px.Utils.UnitTests/Validation/DataValidationTests/DataStructureValidationTests.cs +++ b/Px.Utils.UnitTests/Validation/DataValidationTests/DataStructureValidationTests.cs @@ -21,14 +21,14 @@ public class DataStructureValidatorTest public void AllowedTokenSequences(params EntryType[] tokenSequence) { - List feedbacks = []; + ValidationFeedback feedbacks = []; DataStructureValidator validator = new(); foreach (EntryType tokenType in tokenSequence) { - ValidationFeedback? feedback = validator.Validate([], tokenType, Encoding.UTF8, 1, 1); + KeyValuePair? feedback = validator.Validate([], tokenType, Encoding.UTF8, 1, 1, "foo"); if (feedback is not null) { - feedbacks.Add((ValidationFeedback)feedback); + feedbacks.Add((KeyValuePair)feedback); } } @@ -44,23 +44,23 @@ public void AllowedTokenSequences(params EntryType[] tokenSequence) [DataRow([EntryType.DataItem, EntryType.DataItemSeparator, EntryType.EndOfData])] public void NotAllowedTokenSequences(params EntryType[] tokenSequence) { - List feedbacks = []; + ValidationFeedback feedbacks = []; DataStructureValidator validator = new(); foreach (EntryType tokenType in tokenSequence) { - ValidationFeedback? feedback = validator.Validate([], tokenType, Encoding.UTF8, 1, 1); + KeyValuePair? feedback = validator.Validate([], tokenType, Encoding.UTF8, 1, 1, "foo"); if (feedback is not null) { - feedbacks.Add((ValidationFeedback)feedback); + feedbacks.Add((KeyValuePair)feedback); } } Assert.AreEqual(1, feedbacks.Count); - Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInvalidStructure, feedbacks[0].Rule); - Assert.AreEqual(ValidationFeedbackLevel.Error, feedbacks[0].Level); + Assert.AreEqual(ValidationFeedbackRule.DataValidationFeedbackInvalidStructure, feedbacks.First().Key.Rule); + Assert.AreEqual(ValidationFeedbackLevel.Error, feedbacks.First().Key.Level); List expectedTokens = [ tokenSequence.Length > 1 ? tokenSequence[^2] : EntryType.Unknown, tokenSequence[^1] ]; - Assert.AreEqual(string.Join(",", expectedTokens), feedbacks[0].AdditionalInfo); + Assert.AreEqual(string.Join(",", expectedTokens), feedbacks.First().Value[0].AdditionalInfo); } } } \ No newline at end of file diff --git a/Px.Utils.UnitTests/Validation/DataValidationTests/DataValidationTest.cs b/Px.Utils.UnitTests/Validation/DataValidationTests/DataValidationTest.cs index 8fc5098..68e6eea 100644 --- a/Px.Utils.UnitTests/Validation/DataValidationTests/DataValidationTest.cs +++ b/Px.Utils.UnitTests/Validation/DataValidationTests/DataValidationTest.cs @@ -17,14 +17,17 @@ public void TestValidateWithoutErrors() stream.Seek(6, 0); DataValidator validator = new(stream, 5, 4, "foo", 1, Encoding.Default); - ValidationFeedbackItem[] validationFeedbacks = validator.Validate().FeedbackItems; + ValidationFeedback validationFeedbacks = validator.Validate().FeedbackItems; - foreach (ValidationFeedbackItem validationFeedback in validationFeedbacks) + foreach (KeyValuePair> validationFeedback in validationFeedbacks) { - Logger.LogMessage($"Line {validationFeedback.Feedback.Line}, Char {validationFeedback.Feedback.Character}: " - + $"{validationFeedback.Feedback.Rule} {validationFeedback.Feedback.AdditionalInfo}"); + foreach (ValidationFeedbackValue instance in validationFeedback.Value) + { + Logger.LogMessage($"Line {instance.Line}, Char {instance.Character}: " + + $"{validationFeedback.Key.Rule} {instance.AdditionalInfo}"); + } } - Assert.AreEqual(0, validationFeedbacks.Length); + Assert.AreEqual(0, validationFeedbacks.Count); } [TestMethod] @@ -35,14 +38,17 @@ public async Task TestValidateAsyncWithoutErrors() DataValidator validator = new(stream, 5, 4, "foo", 1, Encoding.Default); ValidationResult result = await validator.ValidateAsync(); - ValidationFeedbackItem[] validationFeedbacks = result.FeedbackItems; + ValidationFeedback validationFeedbacks = result.FeedbackItems; - foreach (ValidationFeedbackItem validationFeedback in validationFeedbacks) + foreach (KeyValuePair> validationFeedback in validationFeedbacks) { - Logger.LogMessage($"Line {validationFeedback.Feedback.Line}, Char {validationFeedback.Feedback.Character}: " - + $"{validationFeedback.Feedback.Rule} {validationFeedback.Feedback.AdditionalInfo}"); + foreach (ValidationFeedbackValue instance in validationFeedback.Value) + { + Logger.LogMessage($"Line {instance.Line}, Char {instance.Character}: " + + $"{validationFeedback.Key.Rule} {instance.AdditionalInfo}"); + } } - Assert.AreEqual(0, validationFeedbacks.Length); + Assert.AreEqual(0, validationFeedbacks.Count); } @@ -53,14 +59,19 @@ public void TestValidateWithErrors() stream.Seek(6, 0); DataValidator validator = new(stream, 5, 4, "foo", 1, Encoding.Default); - ValidationFeedbackItem[] validationFeedbacks = validator.Validate().FeedbackItems; + ValidationFeedback validationFeedbacks = validator.Validate().FeedbackItems; - foreach (ValidationFeedbackItem validationFeedback in validationFeedbacks) + foreach (KeyValuePair> validationFeedback in validationFeedbacks) { - Logger.LogMessage($"Line {validationFeedback.Feedback.Line}, Char {validationFeedback.Feedback.Character}: " - + $"{validationFeedback.Feedback.Rule} {validationFeedback.Feedback.AdditionalInfo}"); + foreach (ValidationFeedbackValue instance in validationFeedback.Value) + { + Logger.LogMessage($"Line {instance.Line}, Char {instance.Character}: " + + $"{validationFeedback.Key.Rule} {instance.AdditionalInfo}"); + } } - Assert.AreEqual(13, validationFeedbacks.Length); + + Assert.AreEqual(7, validationFeedbacks.Count); // Unique feedbacks + Assert.AreEqual(13, validationFeedbacks.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -71,14 +82,19 @@ public async Task TestValidateAsyncWithErrors() DataValidator validator = new(stream, 5, 4, "foo", 1, Encoding.Default); ValidationResult result = await validator.ValidateAsync(); - ValidationFeedbackItem[] validationFeedbacks = result.FeedbackItems; + ValidationFeedback validationFeedbacks = result.FeedbackItems; - foreach (ValidationFeedbackItem validationFeedback in validationFeedbacks) + foreach (KeyValuePair> validationFeedback in validationFeedbacks) { - Logger.LogMessage($"Line {validationFeedback.Feedback.Line}, Char {validationFeedback.Feedback.Character}: " - + $"{validationFeedback.Feedback.Rule} {validationFeedback.Feedback.AdditionalInfo}"); + foreach (ValidationFeedbackValue instance in validationFeedback.Value) + { + Logger.LogMessage($"Line {instance.Line}, Char {instance.Character}: " + + $"{validationFeedback.Key.Rule} {instance.AdditionalInfo}"); + } } - Assert.AreEqual(13, validationFeedbacks.Length); + + Assert.AreEqual(7, validationFeedbacks.Count); // Unique feedbacks + Assert.AreEqual(13, validationFeedbacks.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } } } \ No newline at end of file diff --git a/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorFunctionTests.cs b/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorFunctionTests.cs index ddaca3c..4703b6f 100644 --- a/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorFunctionTests.cs +++ b/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorFunctionTests.cs @@ -19,7 +19,7 @@ public void DuplicatePxFileNameWithoutDuplicateNameReturnsNull() DatabaseFileInfo fileInfo = new("baz.px", "path/to/file", ["fi", "en", "sv"], Encoding.UTF8); // Act - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); // Assert Assert.IsNull(feedback); @@ -37,11 +37,11 @@ public void DuplicatePxFileNameWithDuplicateNameReturnsFeedback() DatabaseFileInfo fileInfo = new("bar.px", "path/to/file", ["fi", "en", "sv"], Encoding.UTF8); // Act - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); // Assert Assert.IsNotNull(feedback); - Assert.AreEqual(ValidationFeedbackRule.DuplicateFileNames, feedback.Value.Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.DuplicateFileNames, feedback.Value.Key.Rule); } [TestMethod] @@ -53,7 +53,7 @@ public void MissingPxFileLanguagesWithoutMissingLanguagesReturnsNull() DatabaseFileInfo fileInfo = new("foo.px", "path/to/file", ["fi", "en", "sv"], Encoding.UTF8); // Act - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); // Assert Assert.IsNull(feedback); @@ -68,11 +68,11 @@ public void MissingPxFileLanguagesWithMissingLanguagesReturnsFeedback() DatabaseFileInfo fileInfo = new("foo.px", "path/to/file", ["fi", "en"], Encoding.UTF8); // Act - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); // Assert Assert.IsNotNull(feedback); - Assert.AreEqual(ValidationFeedbackRule.FileLanguageDiffersFromDatabase, feedback.Value.Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.FileLanguageDiffersFromDatabase, feedback.Value.Key.Rule); } [TestMethod] @@ -84,7 +84,7 @@ public void MismatchingEncodingWithMatchingEncodingReturnsNull() DatabaseFileInfo fileInfo = new("foo.px", "path/to/file", ["fi", "en", "sv"], Encoding.UTF8); // Act - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); // Assert Assert.IsNull(feedback); @@ -99,11 +99,11 @@ public void MismatchingEncodingWithMismatchingEncodingReturnsFeedback() DatabaseFileInfo fileInfo = new("foo.px", "path/to/file", ["fi", "en", "sv"], Encoding.UTF32); // Act - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); // Assert Assert.IsNotNull(feedback); - Assert.AreEqual(ValidationFeedbackRule.FileEncodingDiffersFromDatabase, feedback.Value.Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.FileEncodingDiffersFromDatabase, feedback.Value.Key.Rule); } [TestMethod] @@ -121,7 +121,7 @@ public void MissingAliasFilesWithoutMissingFilesReturnsNull() DatabaseValidationItem directoryInfo = new(path); // Act - ValidationFeedbackItem? feedback = validator.Validate(directoryInfo); + KeyValuePair? feedback = validator.Validate(directoryInfo); // Assert Assert.IsNull(feedback); @@ -141,11 +141,11 @@ public void MissingAliasFilesWithMissingFilesReturnsFeedback() DatabaseValidationItem directoryInfo = new(path); // Act - ValidationFeedbackItem? feedback = validator.Validate(directoryInfo); + KeyValuePair? feedback = validator.Validate(directoryInfo); // Assert Assert.IsNotNull(feedback); - Assert.AreEqual(ValidationFeedbackRule.AliasFileMissing, feedback.Value.Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.AliasFileMissing, feedback.Value.Key.Rule); } } } diff --git a/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorTests.cs b/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorTests.cs index 63e4f0c..2c31f7d 100644 --- a/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorTests.cs +++ b/Px.Utils.UnitTests/Validation/DatabaseValidation/DatabaseValidatorTests.cs @@ -18,7 +18,7 @@ public void ValidateDatabaseWithValidDatabaseReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -33,7 +33,7 @@ public async Task ValidateDatabaseAsyncWithValidDatabaseReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -48,7 +48,8 @@ public void ValidateDatabaseWithCustomValidatorsReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(11, result.FeedbackItems.Length); + Assert.AreEqual(9, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(11, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -63,7 +64,8 @@ public async Task ValidateDatabaseAsyncWithInvalidPxFileReturnsFeedback() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(11, result.FeedbackItems.Length); + Assert.AreEqual(9, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(11, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -87,7 +89,8 @@ public void ValidateDatabaseWithCustomFunctionsReturnsFeedback() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(26, result.FeedbackItems.Length); + Assert.AreEqual(10, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(26, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -111,7 +114,8 @@ public async Task ValidateDatabasAsynceWithCustomFunctionsReturnsFeedback() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(26, result.FeedbackItems.Length); + Assert.AreEqual(10, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(26, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -127,7 +131,8 @@ public void ValidateDatabaseWithSingleLanguagePxFileReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); // LANGUAGES keyword is recommended, but not required, three warning level feedback items are expected - Assert.AreEqual(3, result.FeedbackItems.Length); + Assert.AreEqual(1, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(3, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -143,7 +148,8 @@ public async Task ValidateDatabaseAsyncWithSingleLanguagePxFileReturnsValidResul // Assert Assert.IsNotNull(result, "Validation result should not be null"); // LANGUAGES keyword is recommended, but not required, three warning level feedback items are expected - Assert.AreEqual(3, result.FeedbackItems.Length); + Assert.AreEqual(1, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(3, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } } } diff --git a/Px.Utils.UnitTests/Validation/DatabaseValidation/MockCustomValidatorFunctions.cs b/Px.Utils.UnitTests/Validation/DatabaseValidation/MockCustomValidatorFunctions.cs index a0657d8..6c36cd1 100644 --- a/Px.Utils.UnitTests/Validation/DatabaseValidation/MockCustomValidatorFunctions.cs +++ b/Px.Utils.UnitTests/Validation/DatabaseValidation/MockCustomValidatorFunctions.cs @@ -5,11 +5,11 @@ namespace Px.Utils.UnitTests.Validation.DatabaseValidation { internal sealed class MockCustomDatabaseValidator : IDatabaseValidator { - public ValidationFeedbackItem? Validate(DatabaseValidationItem item) + public KeyValuePair? Validate(DatabaseValidationItem item) { - return new ValidationFeedbackItem( - new ValidationObject("test", 0, []), - new ValidationFeedback(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.AliasFileMissing, 0, 0, "Test error")); + return new ( + new (ValidationFeedbackLevel.Warning, ValidationFeedbackRule.AliasFileMissing), + new ("test", 0, 0, "Test error")); } } } diff --git a/Px.Utils.UnitTests/Validation/PxFileValidationTests/PxFileValidationTests.cs b/Px.Utils.UnitTests/Validation/PxFileValidationTests/PxFileValidationTests.cs index beaa1df..263669d 100644 --- a/Px.Utils.UnitTests/Validation/PxFileValidationTests/PxFileValidationTests.cs +++ b/Px.Utils.UnitTests/Validation/PxFileValidationTests/PxFileValidationTests.cs @@ -21,7 +21,7 @@ public void ValidatePxFileWithMinimalPxFileReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -36,7 +36,7 @@ public async Task ValidatePxFileAsyncWithMinimalPxFileReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -51,7 +51,8 @@ public async Task ValidatePxFileWithInvalidPxFileReturnsFeedbacks() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(11, result.FeedbackItems.Length); + Assert.AreEqual(9, result.FeedbackItems.Count); // Unique feedbacks + Assert.AreEqual(11, result.FeedbackItems.Values.SelectMany(f => f).Count()); // Total feedbacks including duplicates } [TestMethod] @@ -67,7 +68,7 @@ public void ValidatePxFileWithCustomValidatorsReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -83,7 +84,7 @@ public async Task ValidatePxFileAsyncWithCustomValidatorsReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -99,7 +100,7 @@ public void ValidatePxFileWithCustomValidationFunctionsReturnsValidResult() // Assert Assert.IsNotNull(result, "Validation result should not be null"); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } } } diff --git a/Px.Utils.UnitTests/Validation/SyntaxValidationTests/MockCustomSyntaxValidationFunctions.cs b/Px.Utils.UnitTests/Validation/SyntaxValidationTests/MockCustomSyntaxValidationFunctions.cs index 119ec8b..27872e6 100644 --- a/Px.Utils.UnitTests/Validation/SyntaxValidationTests/MockCustomSyntaxValidationFunctions.cs +++ b/Px.Utils.UnitTests/Validation/SyntaxValidationTests/MockCustomSyntaxValidationFunctions.cs @@ -6,17 +6,17 @@ namespace Px.Utils.UnitTests.Validation.SyntaxValidationTests { internal sealed class MockCustomSyntaxValidationFunctions : CustomSyntaxValidationFunctions { - internal static ValidationFeedbackItem? MockEntryValidationFunction(ValidationEntry validationEntry, PxFileSyntaxConf syntaxConf) + internal static KeyValuePair? MockEntryValidationFunction(ValidationEntry validationEntry, PxFileSyntaxConf syntaxConf) { return null; } - internal static ValidationFeedbackItem? MockKeyValuePairValidationFunction(ValidationKeyValuePair validationEntry, PxFileSyntaxConf syntaxConf) + internal static KeyValuePair? MockKeyValuePairValidationFunction(ValidationKeyValuePair validationEntry, PxFileSyntaxConf syntaxConf) { return null; } - internal static ValidationFeedbackItem? MockStructuredValidationFunction(ValidationStructuredEntry validationEntry, PxFileSyntaxConf syntaxConf) + internal static KeyValuePair? MockStructuredValidationFunction(ValidationStructuredEntry validationEntry, PxFileSyntaxConf syntaxConf) { return null; } diff --git a/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationAsyncTests.cs b/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationAsyncTests.cs index daf2a37..9c14bf4 100644 --- a/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationAsyncTests.cs +++ b/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationAsyncTests.cs @@ -10,7 +10,7 @@ namespace Px.Utils.UnitTests.SyntaxValidationTests public class StreamSyntaxValidationAsyncTests { private readonly string filename = "foo"; - private readonly List feedback = []; + private readonly ValidationFeedback feedback = []; [TestMethod] public async Task ValidatePxFileSyntaxAsyncCalledWithMinumalUTF8ReturnsValidResult() diff --git a/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationTests.cs b/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationTests.cs index 589d0bf..ff6eda6 100644 --- a/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationTests.cs +++ b/Px.Utils.UnitTests/Validation/SyntaxValidationTests/StreamSyntaxValidationTests.cs @@ -14,7 +14,7 @@ public class StreamSyntaxValidationTests { private readonly string filename = "foo"; private readonly PxFileSyntaxConf syntaxConf = PxFileSyntaxConf.Default; - private List feedback = []; + private ValidationFeedback feedback = []; private MethodInfo? entryValidationMethod; private MethodInfo? kvpValidationMethod; private MethodInfo? structuredValidationMethod; @@ -61,11 +61,11 @@ public void ValidateObjectsCalledWithMultipleEntriesInSingleLineReturnsWithWarni List functions = [SyntaxValidationFunctions.MultipleEntriesOnLine]; // Act - feedback = entryValidationMethod?.Invoke(null, [entries, functions, syntaxConf]) as List ?? []; + feedback = entryValidationMethod?.Invoke(null, [entries, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(2, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.MultipleEntriesOnOneLine, feedback[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.MultipleEntriesOnOneLine, feedback[0].Feedback.Rule); + Assert.AreEqual(1, feedback.Count); + Assert.AreEqual(2, feedback.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.MultipleEntriesOnOneLine, feedback.First().Key.Rule); } [TestMethod] @@ -104,17 +104,19 @@ public void ValidatePxFileSyntaxCalledWithWithFeedbacksReturnsRightLineAndCharac Encoding? encoding = reader.GetEncoding(stream); stream.Seek(0, SeekOrigin.Begin); SyntaxValidator validator = new(stream, encoding, filename); + ValidationFeedbackKey keyWhiteSpaceFeedbackKey = new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.KeyContainsExcessWhiteSpace); + ValidationFeedbackKey valueWhiteSpaceFeedbackKey = new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.ExcessWhitespaceInValue); // Assert Assert.IsNotNull(encoding, "Encoding should not be null"); // Act SyntaxValidationResult result = validator.Validate(); - Assert.AreEqual(2, result.FeedbackItems.Length); - Assert.AreEqual(9, result.FeedbackItems[0].Feedback.Line); - Assert.AreEqual(18, result.FeedbackItems[0].Feedback.Character); - Assert.AreEqual(12, result.FeedbackItems[1].Feedback.Line); - Assert.AreEqual(40, result.FeedbackItems[1].Feedback.Character); + Assert.AreEqual(2, result.FeedbackItems.Count); + Assert.AreEqual(9, result.FeedbackItems[keyWhiteSpaceFeedbackKey][0].Line); + Assert.AreEqual(18, result.FeedbackItems[keyWhiteSpaceFeedbackKey][0].Character); + Assert.AreEqual(12, result.FeedbackItems[valueWhiteSpaceFeedbackKey][0].Line); + Assert.AreEqual(40, result.FeedbackItems[valueWhiteSpaceFeedbackKey][0].Character); } [TestMethod] @@ -125,10 +127,10 @@ public void ValidateObjectsCalledWithKvpWithMultipleLangParamsReturnsWithError() List functions = [SyntaxValidationFunctions.MoreThanOneLanguageParameter]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.MoreThanOneLanguageParameterSection, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.MoreThanOneLanguageParameterSection, feedback.First().Key.Rule); } @@ -140,10 +142,10 @@ public void ValidateObjectsCalledWithKvpWithMultipleSpecifierParamsSReturnsWithE List functions = [SyntaxValidationFunctions.MoreThanOneSpecifierParameter]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.MoreThanOneSpecifierParameterSection, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.MoreThanOneSpecifierParameterSection, feedback.First().Key.Rule); } [TestMethod] @@ -154,12 +156,12 @@ public void ValidateObjectsCalledWithKvpWithWrongOrderAndMissingKeywordReturnsWi List functions = [SyntaxValidationFunctions.WrongKeyOrderOrMissingKeyword]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(3, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.KeyHasWrongOrder, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.KeyHasWrongOrder, feedback[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.MissingKeyword, feedback[2].Feedback.Rule); + Assert.AreEqual(2, feedback.Count); + Assert.IsTrue(feedback.ContainsKey(new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.KeyHasWrongOrder))); + Assert.IsTrue(feedback.ContainsKey(new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.MissingKeyword))); + Assert.AreEqual(2, feedback[new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.KeyHasWrongOrder)].Count); } [TestMethod] @@ -171,15 +173,18 @@ public void ValidateObjectsCalledWithKvpWithInvalidSpecifiersReturnsWithErrors() SyntaxValidationFunctions.MoreThanTwoSpecifierParts, SyntaxValidationFunctions.SpecifierPartNotEnclosed, SyntaxValidationFunctions.NoDelimiterBetweenSpecifierParts]; + ValidationFeedbackKey missingDelimeterFeedbackKey = new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.SpecifierDelimiterMissing); + ValidationFeedbackKey tooManySpecifiersFeedbackKey = new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.TooManySpecifiers); + ValidationFeedbackKey notEnclosedFeedbackKey = new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.SpecifierPartNotEnclosed); // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(4, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.TooManySpecifiers, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.SpecifierPartNotEnclosed, feedback[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.SpecifierPartNotEnclosed, feedback[2].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.SpecifierDelimiterMissing, feedback[3].Feedback.Rule); + Assert.AreEqual(3, feedback.Count); + Assert.IsTrue(feedback.ContainsKey(missingDelimeterFeedbackKey)); + Assert.IsTrue(feedback.ContainsKey(tooManySpecifiersFeedbackKey)); + Assert.IsTrue(feedback.ContainsKey(notEnclosedFeedbackKey)); + Assert.AreEqual(2, feedback[notEnclosedFeedbackKey].Count); } [TestMethod] @@ -190,12 +195,11 @@ public void ValidateObjectsCalledWithKvpWithIllegalSymbolsInLanguageParamReturns List functions = [SyntaxValidationFunctions.IllegalSymbolsInLanguageParamSection]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(3, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInLanguageParameter, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInLanguageParameter, feedback[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInLanguageParameter, feedback[2].Feedback.Rule); + Assert.AreEqual(1, feedback.Count); + Assert.AreEqual(3, feedback.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInLanguageParameter, feedback.First().Key.Rule); } [TestMethod] @@ -206,28 +210,25 @@ public void ValidateObjectsCalledWithKvpWithIllegalSymbolsInSpecifierParamReturn List functions = [SyntaxValidationFunctions.IllegalSymbolsInSpecifierParamSection]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInSpecifierParameter, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInSpecifierParameter, feedback.First().Key.Rule); } [TestMethod] public void ValidateObjectsCalledWithKvpWithBadValuesReturnsErrors() { - // Arrange List keyValuePairs = SyntaxValidationFixtures.KEYVALUEPAIRS_WITH_BAD_VALUES; List functions = [SyntaxValidationFunctions.InvalidValueFormat]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(4, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback[1].Feedback.Rule); + Assert.AreEqual(1, feedback.Count); + Assert.AreEqual(4, feedback.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback.First().Key.Rule); } [TestMethod] @@ -238,10 +239,10 @@ public void ValidateObjectsCalledWithKvpWithExcessListValueWhitespaceReturnsWith List functions = [SyntaxValidationFunctions.ExcessWhitespaceInValue]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.ExcessWhitespaceInValue, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.ExcessWhitespaceInValue, feedback.First().Key.Rule); } [TestMethod] @@ -252,10 +253,10 @@ public void ValidateObjectsCalledWithKvpWithExcessKeyWhitespaceReturnsWithWarnin List functions = [SyntaxValidationFunctions.KeyContainsExcessWhiteSpace]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.KeyContainsExcessWhiteSpace, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.KeyContainsExcessWhiteSpace, feedback.First().Key.Rule); } [TestMethod] @@ -266,11 +267,11 @@ public void ValidateObjectsCalledWithKvpWithShortMultilineValueReturnsWithWarnin List functions = [SyntaxValidationFunctions.ExcessNewLinesInValue]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(2, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.ExcessNewLinesInValue, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.ExcessNewLinesInValue, feedback[1].Feedback.Rule); + Assert.AreEqual(1, feedback.Count); + Assert.AreEqual(2, feedback.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.ExcessNewLinesInValue, feedback.First().Key.Rule); } [TestMethod] @@ -281,12 +282,12 @@ public void ValidateObjectsCalledWithStructuredEntriesWithInvalidKeywordsReturns List functions = [SyntaxValidationFunctions.KeywordDoesntStartWithALetter, SyntaxValidationFunctions.KeywordContainsIllegalCharacters]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as ValidationFeedback ?? []; - Assert.AreEqual(3, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.KeywordDoesntStartWithALetter, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInKeyword, feedback[1].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInKeyword, feedback[2].Feedback.Rule); + Assert.AreEqual(2, feedback.Count); + Assert.AreEqual(2, feedback.ElementAt(1).Value.Count); + Assert.AreEqual(ValidationFeedbackRule.KeywordDoesntStartWithALetter, feedback.First().Key.Rule); + Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInKeyword, feedback.ElementAt(1).Key.Rule); } [TestMethod] @@ -297,7 +298,7 @@ public void ValidateObjectsCalledWithStructuredEntriesWithValidLanguagesReturnsW List functions = [SyntaxValidationFunctions.IllegalCharactersInLanguageParameter]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(0, feedback.Count); } @@ -310,10 +311,10 @@ public void ValidateObjectsCalledWithStructuredEntriesWithInvalidLanguagesReturn List functions = [SyntaxValidationFunctions.IllegalCharactersInLanguageParameter]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInLanguageParameter, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInLanguageParameter, feedback.First().Key.Rule); } [TestMethod] @@ -324,10 +325,10 @@ public void ValidateObjectsCalledWithStructuredEntriesWithIllegalCharactersInSpe List functions = [SyntaxValidationFunctions.IllegalCharactersInSpecifierParts]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInSpecifierPart, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.IllegalCharactersInSpecifierPart, feedback.First().Key.Rule); } [TestMethod] @@ -338,10 +339,10 @@ public void ValidateObjectsCalledWithEntryWithoutValueReturnsWithError() List functions = [SyntaxValidationFunctions.EntryWithoutValue]; // Act - feedback = entryValidationMethod?.Invoke(null, [entries, functions, syntaxConf]) as List ?? []; + feedback = entryValidationMethod?.Invoke(null, [entries, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.EntryWithoutValue, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.EntryWithoutValue, feedback.First().Key.Rule); } [TestMethod] @@ -352,11 +353,11 @@ public void ValidateObjectsCalledWithStructuredEntriesWithIncompliantLanguagesRe List functions = [SyntaxValidationFunctions.IncompliantLanguage]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf] ) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf] ) as ValidationFeedback ?? []; - Assert.AreEqual(2, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.IncompliantLanguage, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.IncompliantLanguage, feedback[1].Feedback.Rule); + Assert.AreEqual(1, feedback.Count); + Assert.AreEqual(2, feedback.First().Value.Count); + Assert.AreEqual(ValidationFeedbackRule.IncompliantLanguage, feedback.First().Key.Rule); } [TestMethod] @@ -367,11 +368,11 @@ public void ValidateObjectsCalledWithStructuredEntriesWithUnrecommendedKeywordNa List functions = [SyntaxValidationFunctions.KeywordContainsUnderscore, SyntaxValidationFunctions.KeywordIsNotInUpperCase]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf] ) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf] ) as ValidationFeedback ?? []; Assert.AreEqual(2, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.KeywordIsNotInUpperCase, feedback[0].Feedback.Rule); - Assert.AreEqual(ValidationFeedbackRule.KeywordContainsUnderscore, feedback[1].Feedback.Rule); + Assert.IsTrue(feedback.ContainsKey(new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.KeywordIsNotInUpperCase))); + Assert.IsTrue(feedback.ContainsKey(new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.KeywordContainsUnderscore))); } [TestMethod] @@ -382,10 +383,10 @@ public void ValidateObjectsCalledWithLongKeywordReturnsWithWarnings() List functions = [SyntaxValidationFunctions.KeywordIsExcessivelyLong]; // Act - feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as List ?? []; + feedback = structuredValidationMethod?.Invoke(null, [structuredEntries, functions, syntaxConf]) as ValidationFeedback ?? []; Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.KeywordExcessivelyLong, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.KeywordExcessivelyLong, feedback.First().Key.Rule); } [TestMethod] @@ -401,8 +402,8 @@ public void GetValueTypeFromStringCalledWithValidListsValuesCorrectValueType(str List functions = [SyntaxValidationFunctions.InvalidValueFormat]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; - Utils.Validation.ValueType? valueType = getValueTypeFromStringMethod?.Invoke(null, [keyValuePairs[0].KeyValuePair.Value, PxFileSyntaxConf.Default]) as Utils.Validation.ValueType?; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; + Utils.Validation.ValueType? valueType = getValueTypeFromStringMethod?.Invoke(null, [keyValuePairs.First().KeyValuePair.Value, PxFileSyntaxConf.Default]) as Utils.Validation.ValueType?; // Assert Assert.AreEqual(Utils.Validation.ValueType.ListOfStrings, valueType); @@ -431,8 +432,8 @@ public void CorrectlyDefinedRangeAndSeriesTimeValuesReturnCorrectValueType(strin List functions = [SyntaxValidationFunctions.InvalidValueFormat]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; - Utils.Validation.ValueType? valueType = getValueTypeFromStringMethod?.Invoke(null, [keyValuePairs[0].KeyValuePair.Value, PxFileSyntaxConf.Default]) as Utils.Validation.ValueType?; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; + Utils.Validation.ValueType? valueType = getValueTypeFromStringMethod?.Invoke(null, [keyValuePairs.First().KeyValuePair.Value, PxFileSyntaxConf.Default]) as Utils.Validation.ValueType?; // Assert Assert.AreEqual(0, feedback.Count); @@ -461,14 +462,14 @@ public void IncorrectlyDefinedRangeAndSeriesTimeValuesReturnWithErrors(string ti List functions = [SyntaxValidationFunctions.InvalidValueFormat]; // Act - feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as List ?? []; - Utils.Validation.ValueType? valueType = getValueTypeFromStringMethod?.Invoke(null, [keyValuePairs[0].KeyValuePair.Value, PxFileSyntaxConf.Default]) as Utils.Validation.ValueType?; + feedback = kvpValidationMethod?.Invoke(null, [keyValuePairs, functions, syntaxConf]) as ValidationFeedback ?? []; + Utils.Validation.ValueType? valueType = getValueTypeFromStringMethod?.Invoke(null, [keyValuePairs.First().KeyValuePair.Value, PxFileSyntaxConf.Default]) as Utils.Validation.ValueType?; // Assert if (type is null) { Assert.AreEqual(1, feedback.Count); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback[0].Feedback.Rule); + Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, feedback.First().Key.Rule); } Assert.AreEqual(type, valueType); } @@ -489,7 +490,7 @@ public void ValidatePxFileSyntaxCalledWithTimevalsSRetunrsWithValidResult() // Act SyntaxValidationResult result = validator.Validate(); - Assert.AreEqual(0, result.FeedbackItems.Length); + Assert.AreEqual(0, result.FeedbackItems.Count); } [TestMethod] @@ -508,13 +509,13 @@ public void ValidatePxFileSyntaxCalledWithBadTimevalsReturnsErrors() // Act SyntaxValidationResult result = validator.Validate(); - Assert.AreEqual(2, result.FeedbackItems.Length); - Assert.AreEqual(9, result.FeedbackItems[0].Feedback.Line); - Assert.AreEqual(16, result.FeedbackItems[0].Feedback.Character); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, result.FeedbackItems[0].Feedback.Rule); - Assert.AreEqual(10, result.FeedbackItems[1].Feedback.Line); - Assert.AreEqual(16, result.FeedbackItems[1].Feedback.Character); - Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, result.FeedbackItems[1].Feedback.Rule); + Assert.AreEqual(1, result.FeedbackItems.Count); + Assert.AreEqual(9, result.FeedbackItems.First().Value[0].Line); + Assert.AreEqual(16, result.FeedbackItems.First().Value[0].Character); + Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, result.FeedbackItems.First().Key.Rule); + Assert.AreEqual(10, result.FeedbackItems.First().Value[1].Line); + Assert.AreEqual(16, result.FeedbackItems.First().Value[1].Character); + Assert.AreEqual(ValidationFeedbackRule.InvalidValueFormat, result.FeedbackItems.First().Key.Rule); } [TestMethod] diff --git a/Px.Utils/Validation/ContentValidation/ContentValidationResult.cs b/Px.Utils/Validation/ContentValidation/ContentValidationResult.cs index 6939f7c..6b54edb 100644 --- a/Px.Utils/Validation/ContentValidation/ContentValidationResult.cs +++ b/Px.Utils/Validation/ContentValidation/ContentValidationResult.cs @@ -7,7 +7,7 @@ namespace Px.Utils.Validation.ContentValidation /// An array of objects gathered during the metadata content validation process. /// Expected length of each data row. /// Expected data column length/amount of data rows. - public sealed class ContentValidationResult(ValidationFeedbackItem[] feedbackItems, int dataRowLength, int dataRowAmount) : ValidationResult(feedbackItems) + public sealed class ContentValidationResult(ValidationFeedback feedbackItems, int dataRowLength, int dataRowAmount) : ValidationResult(feedbackItems) { public int DataRowLength { get; } = dataRowLength; public int DataRowAmount { get; } = dataRowAmount; diff --git a/Px.Utils/Validation/ContentValidation/ContentValidator.UtilityMethods.cs b/Px.Utils/Validation/ContentValidation/ContentValidator.UtilityMethods.cs index 4ffe6a5..38c7151 100644 --- a/Px.Utils/Validation/ContentValidation/ContentValidator.UtilityMethods.cs +++ b/Px.Utils/Validation/ContentValidation/ContentValidator.UtilityMethods.cs @@ -21,7 +21,7 @@ private static Dictionary, string[]> FindDimensionV ValidationStructuredEntry[] entries, PxFileSyntaxConf syntaxConf, Dictionary? dimensions, - ref List feedbackItems, + ref ValidationFeedback feedbackItems, string filename) { if (dimensions is null) @@ -53,18 +53,13 @@ private static Dictionary, string[]> FindDimensionV } else { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.VariableValuesMissing, - 0, - 0, - $"{dimension}, {language}" - ); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.VariableValuesMissing), + new(filename, 0, 0, $"{dimension}, {language}") + ); - feedbackItems.Add(new ValidationFeedbackItem( - new ValidationObject(filename, 0, []), - feedback - )); + feedbackItems.Add(feedback); } } } @@ -80,9 +75,8 @@ private static Dictionary, string[]> FindDimensionV /// Name of the content dimension value requiring the entry /// Object that stores required information about the validation process /// Optional that indicates if the keyword entry is recommended and should yield a warning if not found - /// Returns a object with an error if required entry is not found - /// or with a warning if the entry specifiers are defined in an unexpected way - private static ValidationFeedbackItem? FindContentVariableKey( + /// Returns a key value pair containing information about the validation violation if required or recommended key is not found. + private static KeyValuePair? FindContentDimensionKey( ValidationStructuredEntry[] entries, string keyword, KeyValuePair languageAndDimensionPair, @@ -101,18 +95,11 @@ private static Dictionary, string[]> FindDimensionV if (entry is null) { - ValidationFeedback feedback = new ( - recommended ? ValidationFeedbackLevel.Warning : ValidationFeedbackLevel.Error, - recommended ? ValidationFeedbackRule.RecommendedKeyMissing : ValidationFeedbackRule.RequiredKeyMissing, - 0, - 0, - $"{keyword}, {language}, {dimensionName}, {dimensionValueName}" - ); - return - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ); + return new KeyValuePair ( + new(recommended ? ValidationFeedbackLevel.Warning : ValidationFeedbackLevel.Error, + recommended ? ValidationFeedbackRule.RecommendedKeyMissing : ValidationFeedbackRule.RequiredKeyMissing), + new(validator._filename, 0, 0, $"{keyword}, {language}, {dimensionName}, {dimensionValueName}") + ); } else if (entry.Key.FirstSpecifier is null || entry.Key.SecondSpecifier is null) { @@ -121,19 +108,11 @@ private static Dictionary, string[]> FindDimensionV 0, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.RecommendedSpecifierDefinitionMissing, - feedbackIndexes.Key, - 0, - $"{keyword}, {language}, {dimensionName}, {dimensionValueName}" - ); - - return - new ValidationFeedbackItem( - entry, - feedback - ); + return new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.RecommendedSpecifierDefinitionMissing), + new(validator._filename, feedbackIndexes.Key, feedbackIndexes.Value, $"{keyword}, {language}, {dimensionName}, {dimensionValueName}") + ); } return null; @@ -147,8 +126,8 @@ private static Dictionary, string[]> FindDimensionV /// Language that the function searches the entry for /// Object that stores required information about the validation process /// Name of the dimension - /// Returns a object with a warning if the recommended entry is not found - private static ValidationFeedbackItem? FindDimensionRecommendedKey( + /// Returns a key value pair containing information about a validation violation warning if the recommended entry is not found + private static KeyValuePair? FindDimensionRecommendedKey( ValidationStructuredEntry[] entries, string keyword, string language, ContentValidator validator, @@ -161,17 +140,11 @@ private static Dictionary, string[]> FindDimensionV if (entry is null) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.RecommendedKeyMissing, - 0, - 0, - $"{language}, {keyword}, {dimensionName}"); - - return new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ); + return new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.RecommendedKeyMissing), + new(validator._filename, 0, 0, $"{keyword}, {language}, {dimensionName}") + ); } return null; @@ -186,8 +159,8 @@ private static Dictionary, string[]> FindDimensionV /// Object that provides information of the ongoing content validation process /// KeyValuePair that contains the processed language as key and the dimension name as value /// Name of the content dimension value to look entries for - /// Returns a list of objects if required entries are not found - private static List ProcessContentDimensionValue( + /// Returns a object containing information of missing required entries + private static ValidationFeedback ProcessContentDimensionValue( string[] languageSpecificKeywords, string[] commonKeywords, string[] recommendedKeywords, @@ -196,13 +169,13 @@ private static List ProcessContentDimensionValue( KeyValuePair languageAndDimensionPair, string valueName) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; foreach (string keyword in languageSpecificKeywords) { - ValidationFeedbackItem? issue = FindContentVariableKey(entries, keyword, languageAndDimensionPair, valueName, validator); + KeyValuePair? issue = FindContentDimensionKey(entries, keyword, languageAndDimensionPair, valueName, validator); if (issue is not null) { - feedbackItems.Add((ValidationFeedbackItem)issue); + feedbackItems.Add((KeyValuePair)issue); } } @@ -210,18 +183,18 @@ private static List ProcessContentDimensionValue( { foreach (string keyword in commonKeywords) { - ValidationFeedbackItem? issue = FindContentVariableKey(entries, keyword, languageAndDimensionPair, valueName, validator); + KeyValuePair ? issue = FindContentDimensionKey(entries, keyword, languageAndDimensionPair, valueName, validator); if (issue is not null) { - feedbackItems.Add((ValidationFeedbackItem)issue); + feedbackItems.Add((KeyValuePair)issue); } } foreach (string keyword in recommendedKeywords) { - ValidationFeedbackItem? issue = FindContentVariableKey(entries, keyword, languageAndDimensionPair, valueName, validator, true); + KeyValuePair? issue = FindContentDimensionKey(entries, keyword, languageAndDimensionPair, valueName, validator, true); if (issue is not null) { - feedbackItems.Add((ValidationFeedbackItem)issue); + feedbackItems.Add((KeyValuePair)issue); } } } @@ -238,8 +211,8 @@ private static List ProcessContentDimensionValue( /// Language assigned to the currently processed dimension /// Object that provides information of the ongoing content validation process /// Name of the dimension currently being processed - /// - private static List ProcessDimension( + /// Returns a object containing information of missing dimension entries + private static ValidationFeedback ProcessDimension( string[] keywords, string dimensionTypeKeyword, ValidationStructuredEntry[] entries, @@ -247,22 +220,22 @@ private static List ProcessDimension( ContentValidator validator, string dimensionName) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; foreach (string keyword in keywords) { - ValidationFeedbackItem? keywordFeedback = FindDimensionRecommendedKey(entries, keyword, language, validator, dimensionName); + KeyValuePair? keywordFeedback = FindDimensionRecommendedKey(entries, keyword, language, validator, dimensionName); if (keywordFeedback is not null) { - feedbackItems.Add((ValidationFeedbackItem)keywordFeedback); + feedbackItems.Add((KeyValuePair)keywordFeedback); } } if (language == validator._defaultLanguage) { - ValidationFeedbackItem? variableTypeFeedback = FindDimensionRecommendedKey(entries, dimensionTypeKeyword, language, validator, dimensionName); + KeyValuePair? variableTypeFeedback = FindDimensionRecommendedKey(entries, dimensionTypeKeyword, language, validator, dimensionName); if (variableTypeFeedback is not null) { - feedbackItems.Add((ValidationFeedbackItem)variableTypeFeedback); + feedbackItems.Add((KeyValuePair)variableTypeFeedback); } } return feedbackItems; diff --git a/Px.Utils/Validation/ContentValidation/ContentValidator.ValidationFunctions.cs b/Px.Utils/Validation/ContentValidation/ContentValidator.ValidationFunctions.cs index 8ddfa40..f2c13aa 100644 --- a/Px.Utils/Validation/ContentValidation/ContentValidator.ValidationFunctions.cs +++ b/Px.Utils/Validation/ContentValidation/ContentValidator.ValidationFunctions.cs @@ -4,8 +4,8 @@ namespace Px.Utils.Validation.ContentValidation { - public delegate ValidationFeedbackItem[]? ContentValidationEntryValidator(ValidationStructuredEntry entry, ContentValidator validator); - public delegate ValidationFeedbackItem[]? ContentValidationFindKeywordValidator(ValidationStructuredEntry[] entries, ContentValidator validator); + public delegate ValidationFeedback? ContentValidationEntryValidator(ValidationStructuredEntry entry, ContentValidator validator); + public delegate ValidationFeedback? ContentValidationFindKeywordValidator(ValidationStructuredEntry[] entries, ContentValidator validator); /// /// Collection of functions for validating Px file metadata contents @@ -41,8 +41,9 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// Null if no issues are found. objects are returned if entry defining default language is not found or if more than one are found. - public static ValidationFeedbackItem[]? ValidateFindDefaultLanguage(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Null if no issues are found. + /// Key value pairs containing information about rule violations are returned if entry defining default language is not found or if more than one are found. + public static ValidationFeedback? ValidateFindDefaultLanguage(ValidationStructuredEntry[] entries, ContentValidator validator) { ValidationStructuredEntry[] langEntries = entries.Where( e => e.Key.Keyword.Equals(validator.SyntaxConf.Tokens.KeyWords.DefaultLanguage, StringComparison.Ordinal)).ToArray(); @@ -54,36 +55,26 @@ public sealed partial class ContentValidator 0, entries[0].LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MultipleInstancesOfUniqueKey, + KeyValuePair feedback = new ( + new (ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MultipleInstancesOfUniqueKey), + new(validator._filename, feedbackIndexes.Key, 0, $"{validator.SyntaxConf.Tokens.KeyWords.DefaultLanguage}: " + string.Join(", ", entries.Select(e => e.Value).ToArray()) - ); + )); - return [ - new ValidationFeedbackItem( - entries[0], - feedback - ), - ]; + return new(feedback); } else if (langEntries.Length == 0) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MissingDefaultLanguage, - 0, - 0 - ); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MissingDefaultLanguage), + new(validator._filename, 0,0) + ); - return [ - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ), - ]; + return new(feedback); } validator._defaultLanguage = SyntaxValidationUtilityMethods.CleanString(langEntries[0].Value, validator.SyntaxConf); @@ -95,9 +86,9 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// Null if no issues are found. object with a warning is returned if available languages entry is not found. + /// Null if no issues are found. Key value pair containing information about the rule violation with a warning is returned if available languages entry is not found. /// Error is returned if multiple entries are found. - public static ValidationFeedbackItem[]? ValidateFindAvailableLanguages(ValidationStructuredEntry[] entries, ContentValidator validator) + public static ValidationFeedback? ValidateFindAvailableLanguages(ValidationStructuredEntry[] entries, ContentValidator validator) { ValidationStructuredEntry[] availableLanguageEntries = entries .Where(e => e.Key.Keyword.Equals(validator.SyntaxConf.Tokens.KeyWords.AvailableLanguages, StringComparison.Ordinal)) @@ -110,20 +101,16 @@ public sealed partial class ContentValidator 0, entries[0].LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MultipleInstancesOfUniqueKey, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MultipleInstancesOfUniqueKey), + new(validator._filename, feedbackIndexes.Key, 0, - $"{validator.SyntaxConf.Tokens.KeyWords.AvailableLanguages}: " + string.Join(", ", entries.Select(e => e.Value).ToArray()) - ); + $"{validator.SyntaxConf.Tokens.KeyWords.AvailableLanguages}: " + string.Join(", ", entries.Select(e => e.Value).ToArray())) + ); - return [ - new ValidationFeedbackItem( - entries[0], - feedback - ) - ]; + return new(feedback); } if (availableLanguageEntries.Length == 1) @@ -135,20 +122,16 @@ public sealed partial class ContentValidator } else { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.RecommendedKeyMissing, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.RecommendedKeyMissing), + new(validator._filename, 0, 0, - validator.SyntaxConf.Tokens.KeyWords.AvailableLanguages - ); + validator.SyntaxConf.Tokens.KeyWords.AvailableLanguages) + ); - return [ - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ) - ]; + return new(feedback); } } @@ -157,8 +140,9 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// Null of no issues are found. object is returned if default language is not defined in the available languages entry - public static ValidationFeedbackItem[]? ValidateDefaultLanguageDefinedInAvailableLanguages(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Null if no issues are found. + /// Key value pair containing information about the rule violation is returned if default language is not defined in the available languages entry + public static ValidationFeedback? ValidateDefaultLanguageDefinedInAvailableLanguages(ValidationStructuredEntry[] entries, ContentValidator validator) { if (validator._availableLanguages is not null && !validator._availableLanguages.Contains(validator._defaultLanguage)) { @@ -174,20 +158,16 @@ public sealed partial class ContentValidator 0, defaultLanguageEntry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.UndefinedLanguageFound, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.UndefinedLanguageFound), + new(validator._filename, feedbackIndexes.Key, 0, - validator._defaultLanguage - ); + validator._defaultLanguage) + ); - return [ - new ValidationFeedbackItem( - defaultLanguageEntry, - feedback - ) - ]; + return new(feedback); } return null; @@ -198,10 +178,10 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects are returned if content dimension entry is not found for any available language - public static ValidationFeedbackItem[]? ValidateFindContentDimension(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if content dimension entry is not found for any available language + public static ValidationFeedback? ValidateFindContentDimension(ValidationStructuredEntry[] entries, ContentValidator validator) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; ValidationStructuredEntry[] contentDimensionEntries = entries .Where(e => e.Key.Keyword.Equals(validator.SyntaxConf.Tokens.KeyWords.ContentVariableIdentifier, StringComparison.Ordinal)) .ToArray(); @@ -213,19 +193,16 @@ public sealed partial class ContentValidator ValidationStructuredEntry? contentDimension = Array.Find(contentDimensionEntries, c => c.Key.Language == language || (c.Key.Language is null && language == defaultLanguage)); if (contentDimension is null) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.RecommendedKeyMissing, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.RecommendedKeyMissing), + new(validator._filename, 0, 0, - $"{validator.SyntaxConf.Tokens.KeyWords.ContentVariableIdentifier}, {language}" - ); - - feedbackItems.Add( - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - )); + $"{validator.SyntaxConf.Tokens.KeyWords.ContentVariableIdentifier}, {language}") + ); + + feedbackItems.Add(feedback); } } @@ -233,7 +210,7 @@ public sealed partial class ContentValidator e => e.Key.Language ?? defaultLanguage, e => e.Value); - return [.. feedbackItems]; + return feedbackItems; } /// @@ -241,10 +218,10 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects are returned if entries required keywords are not found - public static ValidationFeedbackItem[]? ValidateFindRequiredCommonKeys(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if entries required keywords are not found + public static ValidationFeedback? ValidateFindRequiredCommonKeys(ValidationStructuredEntry[] entries, ContentValidator validator) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; string[] alwaysRequiredKeywords = [ validator.SyntaxConf.Tokens.KeyWords.Charset, @@ -256,24 +233,20 @@ public sealed partial class ContentValidator { if (!Array.Exists(entries, e => e.Key.Keyword.Equals(keyword, StringComparison.Ordinal))) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.RequiredKeyMissing, - 0, - 0, - keyword - ); - - feedbackItems.Add( - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ) + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.RequiredKeyMissing), + new(validator._filename, + 0, + 0, + keyword) ); + + feedbackItems.Add(feedback); } } - return [.. feedbackItems]; + return feedbackItems; } /// @@ -281,27 +254,21 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects are returned if stub and heading dimension entries are not found for any available language - public static ValidationFeedbackItem[]? ValidateFindStubAndHeading(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if stub and heading dimension entries are not found for any available language + public static ValidationFeedback? ValidateFindStubAndHeading(ValidationStructuredEntry[] entries, ContentValidator validator) { ValidationStructuredEntry[] stubEntries = entries.Where(e => e.Key.Keyword.Equals(validator.SyntaxConf.Tokens.KeyWords.StubDimensions, StringComparison.Ordinal)).ToArray(); ValidationStructuredEntry[] headingEntries = entries.Where(e => e.Key.Keyword.Equals(validator.SyntaxConf.Tokens.KeyWords.HeadingDimensions, StringComparison.Ordinal)).ToArray(); if (stubEntries.Length == 0 && headingEntries.Length == 0) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MissingStubAndHeading, - 0, - 0 - ); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MissingStubAndHeading), + new(validator._filename, 0, 0) + ); - return [ - new( - new ValidationObject(validator._filename, 0, []), - feedback - ) - ]; + return new(feedback); } string defaultLanguage = validator._defaultLanguage ?? string.Empty; @@ -310,7 +277,7 @@ public sealed partial class ContentValidator validator._headingDimensionNames = GetDimensionNames(headingEntries, defaultLanguage, validator.SyntaxConf); - List feedbackItems = []; + ValidationFeedback feedbackItems = []; string[] languages = validator._availableLanguages ?? [defaultLanguage]; @@ -320,24 +287,20 @@ public sealed partial class ContentValidator && (validator._headingDimensionNames is null || !validator._headingDimensionNames.ContainsKey(language))) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MissingStubAndHeading, - 0, - 0, - $"{language}" - ); - - feedbackItems.Add( - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ) - ); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MissingStubAndHeading), + new(validator._filename, + 0, + 0, + $"{language}") + ); + + feedbackItems.Add(feedback); } } - return [.. feedbackItems]; + return feedbackItems; } /// @@ -345,10 +308,10 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects with warning are returned if recommended keys are missing - public static ValidationFeedbackItem[]? ValidateFindRecommendedKeys(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if recommended keys are missing + public static ValidationFeedback? ValidateFindRecommendedKeys(ValidationStructuredEntry[] entries, ContentValidator validator) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; string[] commonKeys = [ @@ -363,20 +326,16 @@ public sealed partial class ContentValidator { if (!Array.Exists(entries, e => e.Key.Keyword.Equals(keyword, StringComparison.Ordinal))) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.RecommendedKeyMissing, - 0, - 0, - keyword - ); - - feedbackItems.Add( - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ) - ); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.RecommendedKeyMissing), + new(validator._filename, + 0, + 0, + keyword) + ); + + feedbackItems.Add(feedback); } } @@ -390,25 +349,21 @@ public sealed partial class ContentValidator if (!Array.Exists(entries, e => e.Key.Keyword.Equals(keyword, StringComparison.Ordinal) && (e.Key.Language == language || (language == defaultLanguage && e.Key.Language is null)))) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.RecommendedKeyMissing, - 0, - 0, - $"{language}, {keyword}" - ); - - feedbackItems.Add( - new ValidationFeedbackItem( - new ValidationObject(validator._filename, 0, []), - feedback - ) - ); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.RecommendedKeyMissing), + new(validator._filename, + 0, + 0, + $"{language}, {keyword}") + ); + + feedbackItems.Add(feedback); } } } - return [.. feedbackItems]; + return feedbackItems; } /// @@ -416,10 +371,10 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects are returned if values are missing for any dimension - public static ValidationFeedbackItem[]? ValidateFindDimensionValues(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if values are missing for any dimension + public static ValidationFeedback? ValidateFindDimensionValues(ValidationStructuredEntry[] entries, ContentValidator validator) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; ValidationStructuredEntry[] dimensionEntries = entries.Where( e => e.Key.Keyword.Equals(validator.SyntaxConf.Tokens.KeyWords.VariableValues, StringComparison.Ordinal)).ToArray(); @@ -451,7 +406,7 @@ public sealed partial class ContentValidator } } - return [.. feedbackItems]; + return feedbackItems; } /// @@ -459,10 +414,11 @@ public sealed partial class ContentValidator /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects are returned if required entries are missing. Warnings are returned if entries are defined in an unrecommended way - public static ValidationFeedbackItem[]? ValidateFindContentDimensionKeys(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if required entries are missing. + /// Warnings are returned if entries are defined in an unrecommended way + public static ValidationFeedback? ValidateFindContentDimensionKeys(ValidationStructuredEntry[] entries, ContentValidator validator) { - List? feedbackItems = []; + ValidationFeedback feedbackItems = []; string[] languageSpecificKeywords = [ @@ -494,12 +450,12 @@ validator._contentDimensionNames is not null ? { foreach (string dimensionValueName in kvp.Value) { - List items = ProcessContentDimensionValue(languageSpecificKeywords, requiredKeywords, recommendedKeywords, entries, validator, kvp.Key, dimensionValueName); + ValidationFeedback items = ProcessContentDimensionValue(languageSpecificKeywords, requiredKeywords, recommendedKeywords, entries, validator, kvp.Key, dimensionValueName); feedbackItems.AddRange(items); } } - return [.. feedbackItems]; + return feedbackItems; } /// @@ -507,10 +463,10 @@ validator._contentDimensionNames is not null ? /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects with warnings are returned if any dimensions are missing recommended entries related to them - public static ValidationFeedbackItem[]? ValidateFindDimensionRecommendedKeys(ValidationStructuredEntry[] entries, ContentValidator validator) + /// Key value pairs containing information about the rule violation are returned if any dimensions are missing recommended entries related to them + public static ValidationFeedback? ValidateFindDimensionRecommendedKeys(ValidationStructuredEntry[] entries, ContentValidator validator) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; string[] dimensionRecommendedKeywords = [ @@ -527,15 +483,20 @@ validator._contentDimensionNames is not null ? foreach (KeyValuePair languageDimensions in allDimensions) { - ValidationFeedbackItem? timeValFeedback = FindDimensionRecommendedKey(entries, validator.SyntaxConf.Tokens.KeyWords.TimeVal, languageDimensions.Key, validator); + KeyValuePair? timeValFeedback = FindDimensionRecommendedKey( + entries, + validator.SyntaxConf.Tokens.KeyWords.TimeVal, + languageDimensions.Key, + validator); + if (timeValFeedback is not null) { - feedbackItems.Add((ValidationFeedbackItem)timeValFeedback); + feedbackItems.Add((KeyValuePair)timeValFeedback); } foreach (string dimension in languageDimensions.Value) { - List dimensionFeedback = ProcessDimension( + ValidationFeedback dimensionFeedback = ProcessDimension( dimensionRecommendedKeywords, validator.SyntaxConf.Tokens.KeyWords.DimensionType, entries, @@ -546,16 +507,16 @@ validator._contentDimensionNames is not null ? } } - return [.. feedbackItems]; + return feedbackItems; } /// - /// + /// Validates that given entry does not contain specifiers if it is not allowed to have them based on keyword. /// /// Px file metadata entries in an array of objects /// object that stores information that is gathered during the validation process - /// objects are returned if - public static ValidationFeedbackItem[]? ValidateUnexpectedSpecifiers(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if an unexpected specifier is detected. + public static ValidationFeedback? ValidateUnexpectedSpecifiers(ValidationStructuredEntry entry, ContentValidator validator) { string[] noSpecifierAllowedKeywords = [ @@ -582,20 +543,16 @@ validator._contentDimensionNames is not null ? 0, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalSpecifierDefinitionFound, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalSpecifierDefinitionFound), + new(validator._filename, feedbackIndexes.Key, 0, - $"{entry.Key.Keyword}: {entry.Key.FirstSpecifier}, {entry.Key.SecondSpecifier}" - ); + $"{entry.Key.Keyword}: {entry.Key.FirstSpecifier}, {entry.Key.SecondSpecifier}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } return null; @@ -606,8 +563,8 @@ validator._contentDimensionNames is not null ? /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// objects are returned if an illegal or unrecommended language parameter is detected in the entry - public static ValidationFeedbackItem[]? ValidateUnexpectedLanguageParams(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if an illegal or unrecommended language parameter is detected in the entry + public static ValidationFeedback? ValidateUnexpectedLanguageParams(ValidationStructuredEntry entry, ContentValidator validator) { string[] noLanguageParameterAllowedKeywords = [ validator.SyntaxConf.Tokens.KeyWords.Charset, @@ -637,35 +594,29 @@ validator._contentDimensionNames is not null ? if (noLanguageParameterAllowedKeywords.Contains(entry.Key.Keyword)) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalLanguageDefinitionFound, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalLanguageDefinitionFound), + new(validator._filename, feedbackIndexes.Key, 0, - $"{entry.Key.Keyword}, {entry.Key.Language}, {entry.Key.FirstSpecifier}, {entry.Key.SecondSpecifier}"); + $"{entry.Key.Keyword}, {entry.Key.Language}, {entry.Key.FirstSpecifier}, {entry.Key.SecondSpecifier}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } else if (noLanguageParameterRecommendedKeywords.Contains(entry.Key.Keyword)) { - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.UnrecommendedLanguageDefinitionFound, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.UnrecommendedLanguageDefinitionFound), + new(validator._filename, feedbackIndexes.Key, 0, - $"{entry.Key.Keyword}, {entry.Key.Language}, {entry.Key.FirstSpecifier}, {entry.Key.SecondSpecifier}"); + $"{entry.Key.Keyword}, {entry.Key.Language}, {entry.Key.FirstSpecifier}, {entry.Key.SecondSpecifier}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } } @@ -677,8 +628,8 @@ validator._contentDimensionNames is not null ? /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// object is returned if an undefined language is found from the entry - public static ValidationFeedbackItem[]? ValidateLanguageParams(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if an undefined language is found from the entry + public static ValidationFeedback? ValidateLanguageParams(ValidationStructuredEntry entry, ContentValidator validator) { if (entry.Key.Language is null) { @@ -692,19 +643,17 @@ validator._contentDimensionNames is not null ? 0, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.UndefinedLanguageFound, + + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.UndefinedLanguageFound), + new(validator._filename, feedbackIndexes.Key, 0, - entry.Key.Language); + entry.Key.Language) + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } return null; @@ -716,10 +665,10 @@ validator._contentDimensionNames is not null ? /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// object is returned if the entry's specifier is defined in an unexpected way - public static ValidationFeedbackItem[]? ValidateSpecifiers(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if the entry's specifier is defined in an unexpected way + public static ValidationFeedback? ValidateSpecifiers(ValidationStructuredEntry entry, ContentValidator validator) { - List feedbackItems = []; + ValidationFeedback feedbackItems = []; if ((entry.Key.FirstSpecifier is null && entry.Key.SecondSpecifier is null) || validator._dimensionValueNames is null) { @@ -749,19 +698,15 @@ validator._contentDimensionNames is not null ? 0, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalSpecifierDefinitionFound, - feedbackIndexes.Key, - 0, - entry.Key.FirstSpecifier); - - feedbackItems.Add( - new ValidationFeedbackItem( - entry, - feedback - ) + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalSpecifierDefinitionFound), + new(validator._filename, + feedbackIndexes.Key, + 0, + entry.Key.FirstSpecifier) ); + feedbackItems.Add(feedback); } else if (entry.Key.SecondSpecifier is not null && !validator._dimensionValueNames.Values.Any(v => v.Contains(entry.Key.SecondSpecifier))) @@ -771,22 +716,19 @@ validator._contentDimensionNames is not null ? 0, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalSpecifierDefinitionFound, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalSpecifierDefinitionFound), + new(validator._filename, feedbackIndexes.Key, 0, - entry.Key.SecondSpecifier); - - feedbackItems.Add( - new ValidationFeedbackItem( - entry, - feedback - ) + entry.Key.SecondSpecifier) ); + + feedbackItems.Add(feedback); } - return [.. feedbackItems]; + return feedbackItems; } /// @@ -794,8 +736,8 @@ validator._contentDimensionNames is not null ? /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// object is returned if an unexpected value type is detected - public static ValidationFeedbackItem[]? ValidateValueTypes(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if an unexpected value type is detected + public static ValidationFeedback? ValidateValueTypes(ValidationStructuredEntry entry, ContentValidator validator) { string[] stringTypes = [ @@ -844,19 +786,16 @@ validator._contentDimensionNames is not null ? entry.ValueStartIndex, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.UnmatchingValueType, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.UnmatchingValueType), + new(validator._filename, feedbackIndexes.Key, feedbackIndexes.Value, - $"{entry.Key.Keyword}: {entry.ValueType}"); + $"{entry.Key.Keyword}: {entry.ValueType}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } return null; @@ -867,8 +806,8 @@ validator._contentDimensionNames is not null ? /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// object is returned if an unexpected value is detected - public static ValidationFeedbackItem[]? ValidateValueContents(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if an unexpected value is detected + public static ValidationFeedback? ValidateValueContents(ValidationStructuredEntry entry, ContentValidator validator) { string[] allowedCharsets = ["ANSI", "Unicode"]; @@ -893,19 +832,16 @@ validator._contentDimensionNames is not null ? entry.ValueStartIndex, entry.LineChangeIndexes); - ValidationFeedback feedback = new( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.InvalidValueFound, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.InvalidValueFound), + new(validator._filename, feedbackIndexes.Key, feedbackIndexes.Value, - $"{entry.Key.Keyword}: {entry.Value}"); + $"{entry.Key.Keyword}: {entry.Value}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } else if (entry.Key.Keyword == validator.SyntaxConf.Tokens.KeyWords.ContentVariableIdentifier) { @@ -921,19 +857,16 @@ validator._contentDimensionNames is not null ? entry.ValueStartIndex, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.InvalidValueFound, - feedbackIndexes.Key, - feedbackIndexes.Value, - $"{entry.Key.Keyword}: {entry.Value}"); - - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.InvalidValueFound), + new(validator._filename, + feedbackIndexes.Key, + feedbackIndexes.Value, + $"{entry.Key.Keyword}: {entry.Value}") + ); + + return new(feedback); } } @@ -945,8 +878,8 @@ validator._contentDimensionNames is not null ? /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// object is returned if an unexpected amount of values is detected - public static ValidationFeedbackItem[]? ValidateValueAmounts(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if an unexpected amount of values is detected + public static ValidationFeedback? ValidateValueAmounts(ValidationStructuredEntry entry, ContentValidator validator) { if (entry.Key.Keyword != validator.SyntaxConf.Tokens.KeyWords.VariableValueCodes || validator._dimensionValueNames is null || @@ -965,19 +898,16 @@ validator._dimensionValueNames is null || entry.ValueStartIndex, entry.LineChangeIndexes); - ValidationFeedback feedback = new( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.UnmatchingValueAmount, - feedbackIndexes.Key, - feedbackIndexes.Value, - $"{entry.Key.Keyword}: {entry.Value}"); + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.UnmatchingValueAmount), + new(validator._filename, + feedbackIndexes.Key, + feedbackIndexes.Value, + $"{entry.Key.Keyword}: {entry.Value}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } return null; @@ -988,8 +918,8 @@ validator._dimensionValueNames is null || /// /// Entry in the Px file metadata. Represented by a object /// object that stores information that is gathered during the validation process - /// object with warning is returned if the found value is not written in upper case - public static ValidationFeedbackItem[]? ValidateValueUppercaseRecommendations(ValidationStructuredEntry entry, ContentValidator validator) + /// Key value pair containing information about the rule violation is returned if the found value is not written in upper case + public static ValidationFeedback? ValidateValueUppercaseRecommendations(ValidationStructuredEntry entry, ContentValidator validator) { string[] recommendedUppercaseValueKeywords = [ validator.SyntaxConf.Tokens.KeyWords.CodePage @@ -1009,19 +939,16 @@ validator._dimensionValueNames is null || entry.ValueStartIndex, entry.LineChangeIndexes); - ValidationFeedback feedback = new ( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.ValueIsNotInUpperCase, + KeyValuePair feedback = new( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.ValueIsNotInUpperCase), + new(validator._filename, feedbackIndexes.Key, entry.ValueStartIndex, - $"{entry.Key.Keyword}: {entry.Value}"); + $"{entry.Key.Keyword}: {entry.Value}") + ); - return [ - new ValidationFeedbackItem( - entry, - feedback - ) - ]; + return new(feedback); } return null; } diff --git a/Px.Utils/Validation/ContentValidation/ContentValidator.cs b/Px.Utils/Validation/ContentValidation/ContentValidator.cs index 158308e..9338547 100644 --- a/Px.Utils/Validation/ContentValidation/ContentValidator.cs +++ b/Px.Utils/Validation/ContentValidation/ContentValidator.cs @@ -65,11 +65,11 @@ public ContentValidationResult Validate() contentValidationFindKeywordFunctions = contentValidationFindKeywordFunctions.Concat(customContentValidationFunctions.CustomContentValidationFindKeywordFunctions); } - List feedbackItems = []; + ValidationFeedback feedbackItems = []; foreach (ContentValidationFindKeywordValidator findingFunction in contentValidationFindKeywordFunctions) { - ValidationFeedbackItem[]? feedback = findingFunction(entries, this); + ValidationFeedback? feedback = findingFunction(entries, this); if (feedback is not null) { feedbackItems.AddRange(feedback); @@ -79,7 +79,7 @@ public ContentValidationResult Validate() { foreach (ValidationStructuredEntry entry in entries) { - ValidationFeedbackItem[]? feedback = entryFunction(entry, this); + ValidationFeedback? feedback = entryFunction(entry, this); if (feedback is not null) { feedbackItems.AddRange(feedback); @@ -90,7 +90,7 @@ public ContentValidationResult Validate() int amountOfDataRows = _stubDimensionNames is not null ? GetProductOfDimensionValues(_stubDimensionNames) : 0; ResetFields(); - return new ContentValidationResult([.. feedbackItems], lengthOfDataRows, amountOfDataRows); + return new ContentValidationResult(feedbackItems, lengthOfDataRows, amountOfDataRows); } #region Interface implementation diff --git a/Px.Utils/Validation/DataValidation/DataValidator.cs b/Px.Utils/Validation/DataValidation/DataValidator.cs index fb53761..f24ab20 100644 --- a/Px.Utils/Validation/DataValidation/DataValidator.cs +++ b/Px.Utils/Validation/DataValidation/DataValidator.cs @@ -46,26 +46,25 @@ public ValidationResult Validate() { SetValidationParameters(); - List validationFeedbacks = []; + ValidationFeedback validationFeedbacks = []; int dataStartIndex = GetStreamIndexOfFirstDataValue(ref validationFeedbacks); if (dataStartIndex == -1) { - validationFeedbacks.Add(new( - new(filename, 0, []), - new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.StartOfDataSectionNotFound, - 0, - 0))); + KeyValuePair feedback = + new(new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.StartOfDataSectionNotFound), + new(filename, 0, 0)); + validationFeedbacks.Add(feedback); - return new ValidationResult([.. validationFeedbacks]); + return new (validationFeedbacks); } stream.Position = dataStartIndex; - ValidationFeedbackItem[] dataStreamFeedbacks = ValidateDataStream(stream); + ValidationFeedback dataStreamFeedbacks = ValidateDataStream(stream); validationFeedbacks.AddRange(dataStreamFeedbacks); ResetValidator(); - return new ValidationResult([..validationFeedbacks]); + return new (validationFeedbacks); } /// @@ -79,27 +78,26 @@ public async Task ValidateAsync(CancellationToken cancellation { SetValidationParameters(); - List validationFeedbacks = []; + ValidationFeedback validationFeedbacks = []; int dataStartIndex = GetStreamIndexOfFirstDataValue(ref validationFeedbacks); if (dataStartIndex == -1) { - validationFeedbacks.Add(new( - new(filename, 0, []), - new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.StartOfDataSectionNotFound, - 0, - 0))); + KeyValuePair feedback = + new(new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.StartOfDataSectionNotFound), + new(filename, 0, 0)); + validationFeedbacks.Add(feedback); - return new ValidationResult([.. validationFeedbacks]); + return new (validationFeedbacks); } stream.Position = dataStartIndex; - ValidationFeedbackItem[] dataStreamFeedbacks = await Task.Factory.StartNew(() => + ValidationFeedback dataStreamFeedbacks = await Task.Factory.StartNew(() => ValidateDataStream(stream, cancellationToken), cancellationToken); validationFeedbacks.AddRange(dataStreamFeedbacks); ResetValidator(); - return new ValidationResult([.. validationFeedbacks]); + return new (validationFeedbacks); } private void SetValidationParameters() @@ -123,9 +121,9 @@ async Task IPxFileValidatorAsync.ValidateAsync(CancellationTok #endregion - private ValidationFeedbackItem[] ValidateDataStream(Stream stream, CancellationToken? cancellationToken = null) + private ValidationFeedback ValidateDataStream(Stream stream, CancellationToken? cancellationToken = null) { - List validationFeedbacks = []; + ValidationFeedback validationFeedbacks = []; byte endOfData = (byte)_conf.Symbols.EntrySeparator; _stringDelimeter = (byte)_conf.Symbols.Value.StringDelimeter; _currentEntry = new(_streamBufferSize); @@ -166,26 +164,23 @@ private ValidationFeedbackItem[] ValidateDataStream(Stream stream, CancellationT if (numOfRows != _lineNumber - 1) { validationFeedbacks.Add(new( - new(filename, _lineNumber + startRow, []), - new( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidRowCount, - _lineNumber + startRow, - _charPosition, - $" Expected {numOfRows} rows, got {_lineNumber - 1} rows." - ))); + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.DataValidationFeedbackInvalidRowCount), + new(filename, _lineNumber + startRow, _charPosition, $" Expected {numOfRows} rows, got {_lineNumber - 1} rows.")) + ); } - return [..validationFeedbacks]; + return validationFeedbacks; } - private void HandleEntryTypeChange(ref List validationFeedbacks) + private void HandleEntryTypeChange(ref ValidationFeedback validationFeedbacks) { if (_currentEntryType == EntryType.Unknown && (_lineNumber > 1 || _charPosition > 0)) { validationFeedbacks.Add(new( - new(filename, _lineNumber + startRow, []), - new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidChar, _lineNumber + startRow, _charPosition))); + new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidChar), + new(filename, _lineNumber + startRow, _charPosition)) + ); } else { @@ -198,18 +193,22 @@ private void HandleEntryTypeChange(ref List validationFe foreach (IDataValidator validator in validators) { - ValidationFeedback? feedback = validator.Validate(_currentEntry, _currentEntryType, _encoding, _lineNumber + startRow, _charPosition); + KeyValuePair? feedback = validator.Validate( + _currentEntry, + _currentEntryType, + _encoding, + _lineNumber + startRow, + _charPosition, + filename); if (feedback is not null) { - validationFeedbacks.Add(new - (new(filename, _lineNumber + startRow, []), - (ValidationFeedback)feedback)); + validationFeedbacks.Add((KeyValuePair)feedback); } } } } - private void HandleNonSeparatorType(ref List validationFeedbacks) + private void HandleNonSeparatorType(ref ValidationFeedback validationFeedbacks) { if (_currentCharacterType == EntryType.DataItem) { @@ -220,11 +219,10 @@ private void HandleNonSeparatorType(ref List validationF if (_currentRowLength != rowLen) { validationFeedbacks.Add(new( - new(filename, _lineNumber + startRow, []), - new ValidationFeedback(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidRowLength, - _lineNumber + startRow, - _charPosition))); + new (ValidationFeedbackLevel.Error, + ValidationFeedbackRule.DataValidationFeedbackInvalidRowLength), + new(filename, _lineNumber + startRow, _charPosition)) + ); } _lineNumber++; _currentRowLength = 0; @@ -245,7 +243,7 @@ private void ResetValidator() _currentRowLength = 0; } - private int GetStreamIndexOfFirstDataValue(ref List feedbacks) + private int GetStreamIndexOfFirstDataValue(ref ValidationFeedback feedbacks) { byte[] buffer = new byte[_streamBufferSize]; int bytesRead; @@ -260,12 +258,11 @@ private int GetStreamIndexOfFirstDataValue(ref List feed } else if (!CharacterConstants.WhitespaceCharacters.Contains((char)buffer[i])) { - feedbacks.Add(new ValidationFeedbackItem( - new(filename, _lineNumber + startRow, []), + feedbacks.Add(new( new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidChar, - _lineNumber + startRow, - _charPosition))); + ValidationFeedbackRule.DataValidationFeedbackInvalidChar), + new(filename, _lineNumber + startRow, _charPosition)) + ); } } } while (bytesRead > 0); @@ -288,6 +285,6 @@ public enum EntryType internal interface IDataValidator { - internal ValidationFeedback? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos); + internal KeyValuePair? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos, string filename); } } \ No newline at end of file diff --git a/Px.Utils/Validation/DataValidation/DataValidatorFunctions.cs b/Px.Utils/Validation/DataValidation/DataValidatorFunctions.cs index a3f359e..131eaaa 100644 --- a/Px.Utils/Validation/DataValidation/DataValidatorFunctions.cs +++ b/Px.Utils/Validation/DataValidation/DataValidatorFunctions.cs @@ -26,13 +26,14 @@ public class DataStringValidator : IDataValidator /// Line number for the validation item. /// Represents the position relative to the line for the validation item. /// object if the entry is not a missing value string sequence, otherwise null. - public ValidationFeedback? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos) + public KeyValuePair? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos, string filename) { string value = encoding.GetString(entry.ToArray()); if (!ValidStringDataItems.Contains(value)) { - return new ValidationFeedback(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidString, lineNumber, charPos, $"{value}"); + return new( + new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidString), + new(filename, lineNumber, charPos, $"{value}")); } else { @@ -56,16 +57,14 @@ public class DataNumberValidator : IDataValidator /// Line number for the validation item. /// Represents the position relative to the line for the validation item. /// object if the entry is not a valid number, otherwise null. - public ValidationFeedback?Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos) + public KeyValuePair? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos, string filename) { if (entry.Count >= MaxLength && !decimal.TryParse(entry.ToArray(), out _)) { - return new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidNumber, - lineNumber, - charPos, - encoding.GetString(entry.ToArray())); + return new( + new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidNumber), + new(filename, lineNumber, charPos, encoding.GetString(entry.ToArray())) + ); } int decimalSeparatorIndex = entry.IndexOf(0x2E); @@ -73,12 +72,10 @@ public class DataNumberValidator : IDataValidator { if (!IsValidIntegerPart(entry, true)) { - return new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidNumber, - lineNumber, - charPos, - encoding.GetString(entry.ToArray())); + return new( + new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidNumber), + new(filename, lineNumber, charPos, encoding.GetString(entry.ToArray())) + ); } else { @@ -87,12 +84,11 @@ public class DataNumberValidator : IDataValidator } else if (decimalSeparatorIndex == 0 || !IsValidIntegerPart(entry[0..decimalSeparatorIndex], false) || !IsValidDecimalPart(entry[decimalSeparatorIndex..])) { - return new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidNumber, - lineNumber, - charPos, - encoding.GetString(entry.ToArray())); + + return new( + new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidNumber), + new(filename, lineNumber, charPos, encoding.GetString(entry.ToArray())) + ); } else { @@ -143,7 +139,7 @@ public class DataSeparatorValidator : IDataValidator /// Line number for the validation item. /// Represents the position relative to the line for the validation item. /// object if the entry is not a valid item separator, otherwise null. - public ValidationFeedback? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos) + public KeyValuePair? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos, string filename) { if (_separator == entry[0]) { @@ -155,11 +151,10 @@ public class DataSeparatorValidator : IDataValidator return null; } - return new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.DataValidationFeedbackInconsistentSeparator, - lineNumber, - charPos); + return new( + new(ValidationFeedbackLevel.Warning, ValidationFeedbackRule.DataValidationFeedbackInconsistentSeparator), + new(filename, lineNumber, charPos) + ); } private const byte Sentinel = 0x0; @@ -188,7 +183,7 @@ public class DataStructureValidator : IDataValidator /// Represents the position relative to the line for the validation item. /// Reference to a list of feedback items to which any validation feedback is added to. /// object if the entry sequence is invalid. Otherwise null. - public ValidationFeedback? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos) + public KeyValuePair? Validate(List entry, EntryType entryType, Encoding encoding, int lineNumber, int charPos, string filename) { if (_allowedPreviousTokens[entryType].Contains(_previousTokenType)) { @@ -199,12 +194,10 @@ public class DataStructureValidator : IDataValidator string additionalInfo = $"{_previousTokenType},{entryType}"; _previousTokenType = entryType; - return new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.DataValidationFeedbackInvalidStructure, - lineNumber, - charPos, - additionalInfo); + return new( + new(ValidationFeedbackLevel.Error, ValidationFeedbackRule.DataValidationFeedbackInvalidStructure), + new(filename, lineNumber, charPos, additionalInfo) + ); } } } \ No newline at end of file diff --git a/Px.Utils/Validation/DatabaseValidation/DatabaseValidator.cs b/Px.Utils/Validation/DatabaseValidation/DatabaseValidator.cs index 33a1f33..a14ceea 100644 --- a/Px.Utils/Validation/DatabaseValidation/DatabaseValidator.cs +++ b/Px.Utils/Validation/DatabaseValidation/DatabaseValidator.cs @@ -33,7 +33,7 @@ public class DatabaseValidator( private readonly IDatabaseValidator[]? _customDirectoryValidators = customDirectoryValidators; private readonly IFileSystem _fileSystem = fileSystem is not null ? fileSystem : new DefaultFileSystem(); - private readonly ConcurrentBag feedbacks = []; + private readonly ValidationFeedback feedbacks = []; private readonly ConcurrentBag pxFiles = []; private readonly ConcurrentBag aliasFiles = []; @@ -60,7 +60,7 @@ public ValidationResult Validate() Task.WaitAll([.. fileTasks]); ValidateDatabaseContents(); - return new ValidationResult([..feedbacks]); + return new (feedbacks); } /// @@ -87,7 +87,7 @@ public async Task ValidateAsync(CancellationToken cancellation await Task.WhenAll(fileTasks); ValidateDatabaseContents(); - return new ValidationResult([.. feedbacks]); + return new (feedbacks); } private void ProcessPxFile(string fileName) @@ -98,10 +98,7 @@ private void ProcessPxFile(string fileName) stream.Position = 0; PxFileValidator validator = new(stream, fileName, fileInfo.Encoding, _syntaxConf); ValidationResult result = validator.Validate(); - foreach (ValidationFeedbackItem feedback in result.FeedbackItems) - { - feedbacks.Add(feedback); - } + feedbacks.AddRange(result.FeedbackItems); } private void ProcessAliasFile(string fileName) @@ -119,10 +116,7 @@ private async Task ProcessPxFileAsync(string fileName, CancellationToken cancell stream.Position = 0; PxFileValidator validator = new(stream, fileName, fileInfo.Encoding, _syntaxConf); ValidationResult result = await validator.ValidateAsync(cancellationToken); - foreach (ValidationFeedbackItem feedback in result.FeedbackItems) - { - feedbacks.Add(feedback); - } + feedbacks.AddRange(result.FeedbackItems); cancellationToken.ThrowIfCancellationRequested(); } @@ -165,10 +159,10 @@ private void ValidatePxFiles(IEnumerable databaseLanguages, Encoding mos { foreach (IDatabaseValidator validator in pxFileValidators) { - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); if (feedback is not null) { - feedbacks.Add((ValidationFeedbackItem)feedback); + feedbacks.Add((KeyValuePair)feedback); } } } @@ -189,10 +183,10 @@ private void ValidateAliasFiles(Encoding mostCommonEncoding) { foreach (IDatabaseValidator validator in aliasFileValidators) { - ValidationFeedbackItem? feedback = validator.Validate(fileInfo); + KeyValuePair? feedback = validator.Validate(fileInfo); if (feedback is not null) { - feedbacks.Add((ValidationFeedbackItem)feedback); + feedbacks.Add((KeyValuePair)feedback); } } } @@ -217,10 +211,10 @@ private void ValidateDirectories(IEnumerable databaseLanguages) foreach (IDatabaseValidator validator in directoryValidators) { - ValidationFeedbackItem? feedback = validator.Validate(new DatabaseValidationItem(directory)); + KeyValuePair? feedback = validator.Validate(new DatabaseValidationItem(directory)); if (feedback is not null) { - feedbacks.Add((ValidationFeedbackItem)feedback); + feedbacks.Add((KeyValuePair)feedback); } } } @@ -240,13 +234,11 @@ private DatabaseFileInfo GetPxFileInfo(string filename, Stream stream) } catch (InvalidPxFileMetadataException e) { - feedbacks.Add(new ValidationFeedbackItem( - new(filename, 0, []), + feedbacks.Add(new( new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.NoEncoding, - 0, 0, - $"Error while reading the encoding of the file {filename}: {e.Message}" - ))); + ValidationFeedbackRule.NoEncoding), + new(filename, 0, 0, $"Error while reading the encoding of the file {filename}: {e.Message}")) + ); } stream.Position = 0; const int bufferSize = 1024; @@ -304,13 +296,11 @@ private async Task GetPxFileInfoAsync(string filename, Stream } catch (InvalidPxFileMetadataException e) { - feedbacks.Add(new ValidationFeedbackItem( - new(filename, 0, []), + feedbacks.Add(new( new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.NoEncoding, - 0, 0, - $"Error while reading the encoding of the file {filename}: {e.Message}" - ))); + ValidationFeedbackRule.NoEncoding), + new(filename, 0, 0, $"Error while reading the encoding of the file {filename}: {e.Message}")) + ); } stream.Position = 0; const int bufferSize = 1024; @@ -403,6 +393,6 @@ public class DatabaseFileInfo(string name, string location, string[] languages, public interface IDatabaseValidator { - public ValidationFeedbackItem? Validate(DatabaseValidationItem item); + public KeyValuePair? Validate(DatabaseValidationItem item); } } diff --git a/Px.Utils/Validation/DatabaseValidation/DatabaseValidatorFunctions.cs b/Px.Utils/Validation/DatabaseValidation/DatabaseValidatorFunctions.cs index 459b3bd..e466f4d 100644 --- a/Px.Utils/Validation/DatabaseValidation/DatabaseValidatorFunctions.cs +++ b/Px.Utils/Validation/DatabaseValidation/DatabaseValidatorFunctions.cs @@ -15,20 +15,17 @@ public class DuplicatePxFileName(List pxFiles) : IDatabaseVali /// Validation function that checks if the filename of the given file is unique within the database /// /// object - in this case subject to validation - /// Null if no issues are found, in case there are multiple files with the same filename. - public ValidationFeedbackItem? Validate(DatabaseValidationItem item) + /// Null if no issues are found, a key value pair containing information about rule violation in case there are multiple files with the same filename. + public KeyValuePair? Validate(DatabaseValidationItem item) { if (item is DatabaseFileInfo fileInfo && _pxFiles.Exists(file => file.Name == fileInfo.Name && file != fileInfo)) { - return new ( - new(fileInfo.Name, 0, []), + return new( new(ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.DuplicateFileNames, - 0, - 0, - $"Duplicate file name: {fileInfo.Name}")); - + ValidationFeedbackRule.DuplicateFileNames), + new(fileInfo.Name, 0, 0, $"Duplicate file name: {fileInfo.Name}") + ); } else { @@ -49,19 +46,17 @@ public class MissingPxFileLanguages(IEnumerable allLanguages) : IDatabas /// Validation function that checks if the given file contains all the languages that should be present in each px file /// /// object - in this case subject to validation - /// Null if no issues are found, in case some languages are missing - public ValidationFeedbackItem? Validate(DatabaseValidationItem item) + /// Null if no issues are found, a key value pair containing information about rule violation> in case some languages are missing + public KeyValuePair? Validate(DatabaseValidationItem item) { if (item is DatabaseFileInfo fileInfo && !_allLanguages.All(lang => fileInfo.Languages.Contains(lang))) { - return new ( - new(fileInfo.Name, 0, []), + return new( new(ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.FileLanguageDiffersFromDatabase, - 0, - 0, - $"Missing languages in file {fileInfo.Name}: {string.Join(", ", _allLanguages.Except(fileInfo.Languages))}")); + ValidationFeedbackRule.FileLanguageDiffersFromDatabase), + new(fileInfo.Name, 0, 0, $"Missing languages in file {fileInfo.Name}: {string.Join(", ", _allLanguages.Except(fileInfo.Languages))}") + ); } else { @@ -82,19 +77,16 @@ public class MismatchingEncoding(Encoding mostCommonEncoding) : IDatabaseValidat /// Validation function that checks if the encoding of the given file is consistent with the most commonly used encoding /// /// object - in this case subject to validation - /// Null if no issues are found, in case the encoding is inconsistent - public ValidationFeedbackItem? Validate(DatabaseValidationItem item) + /// Null if no issues are found, a key value pair containing information about rule violation> in case the encoding is inconsistent + public KeyValuePair? Validate(DatabaseValidationItem item) { if (item is DatabaseFileInfo fileInfo && fileInfo.Encoding != _mostCommonEncoding) { return new ( - new(fileInfo.Name, 0, []), new(ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.FileEncodingDiffersFromDatabase, - 0, - 0, - $"Inconsistent encoding in file {fileInfo.Name}: {fileInfo.Encoding.EncodingName}. " + + ValidationFeedbackRule.FileEncodingDiffersFromDatabase), + new(fileInfo.Name, 0, 0, $"Inconsistent encoding in file {fileInfo.Name}: {fileInfo.Encoding.EncodingName}. " + $"Most commonly used encoding is {_mostCommonEncoding.EncodingName}")); } else @@ -118,21 +110,18 @@ public class MissingAliasFiles(List aliasFiles, IEnumerable /// object subject to validation - /// Null if no issues are found, in case some alias files are missing - public ValidationFeedbackItem? Validate(DatabaseValidationItem item) + /// Null if no issues are found, a key value pair containing information about rule violation> in case some alias files are missing + public KeyValuePair? Validate(DatabaseValidationItem item) { foreach (string language in _allLanguages) { if (!_aliasFiles.Exists(file => file.Languages.Contains(language))) { return new( - new(item.Path, 0, []), new(ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.AliasFileMissing, - 0, - 0, - $"Alias file for {language} in {item.Path} is missing" - )); + ValidationFeedbackRule.AliasFileMissing), + new(item.Path, 0, 0, $"Alias file for {language} in {item.Path} is missing") + ); } } diff --git a/Px.Utils/Validation/IValidationResult.cs b/Px.Utils/Validation/IValidationResult.cs index 56be429..c875e61 100644 --- a/Px.Utils/Validation/IValidationResult.cs +++ b/Px.Utils/Validation/IValidationResult.cs @@ -3,8 +3,9 @@ /// /// Represents a feedback item that was produced during a px file validation operation. /// - public class ValidationResult(ValidationFeedbackItem[] feedbackItems) + /// The feedback items that were produced during the validation operation. + public class ValidationResult(ValidationFeedback feedbackItems) { - public ValidationFeedbackItem[] FeedbackItems { get; } = feedbackItems; + public ValidationFeedback FeedbackItems { get; } = feedbackItems; } } diff --git a/Px.Utils/Validation/PxFileValidator.cs b/Px.Utils/Validation/PxFileValidator.cs index 11a6a86..f7ba13f 100644 --- a/Px.Utils/Validation/PxFileValidator.cs +++ b/Px.Utils/Validation/PxFileValidator.cs @@ -58,7 +58,7 @@ public ValidationResult Validate() encoding ??= Encoding.Default; syntaxConf ??= PxFileSyntaxConf.Default; - List feedbacks = []; + ValidationFeedback feedbacks = []; SyntaxValidator syntaxValidator = new(stream, encoding, filename, syntaxConf, _customSyntaxValidationFunctions, true); SyntaxValidationResult syntaxValidationResult = syntaxValidator.Validate(); feedbacks.AddRange(syntaxValidationResult.FeedbackItems); @@ -70,13 +70,12 @@ public ValidationResult Validate() if (syntaxValidationResult.DataStartStreamPosition == -1) { feedbacks.Add(new( - new(filename, 0, []), new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.StartOfDataSectionNotFound, - 0, 0) + ValidationFeedbackRule.StartOfDataSectionNotFound), + new(filename, 0, 0) )); - return new ValidationResult([.. feedbacks]); + return new (feedbacks); } stream.Position = syntaxValidationResult.DataStartStreamPosition; @@ -100,7 +99,7 @@ public ValidationResult Validate() } } - return new ValidationResult([..feedbacks]); + return new ValidationResult(feedbacks); } /// @@ -113,7 +112,7 @@ public async Task ValidateAsync(CancellationToken cancellation encoding ??= Encoding.Default; syntaxConf ??= PxFileSyntaxConf.Default; - List feedbacks = []; + ValidationFeedback feedbacks = []; SyntaxValidator syntaxValidator = new(stream, encoding, filename, syntaxConf, _customSyntaxValidationFunctions, true); SyntaxValidationResult syntaxValidationResult = await syntaxValidator.ValidateAsync(cancellationToken); feedbacks.AddRange(syntaxValidationResult.FeedbackItems); @@ -125,13 +124,12 @@ public async Task ValidateAsync(CancellationToken cancellation if (syntaxValidationResult.DataStartStreamPosition == -1) { feedbacks.Add(new( - new(filename, 0, []), new(ValidationFeedbackLevel.Error, - ValidationFeedbackRule.StartOfDataSectionNotFound, - 0, 0) - )); + ValidationFeedbackRule.StartOfDataSectionNotFound), + new(filename, 0, 0) + )); - return new ValidationResult([.. feedbacks]); + return new (feedbacks); } stream.Position = syntaxValidationResult.DataStartStreamPosition; @@ -156,7 +154,7 @@ public async Task ValidateAsync(CancellationToken cancellation } } - return new ValidationResult([..feedbacks]); + return new ValidationResult(feedbacks); } } } diff --git a/Px.Utils/Validation/SyntaxValidation/SyntaxValidationFunctions.cs b/Px.Utils/Validation/SyntaxValidation/SyntaxValidationFunctions.cs index e17cb33..2985f2a 100644 --- a/Px.Utils/Validation/SyntaxValidation/SyntaxValidationFunctions.cs +++ b/Px.Utils/Validation/SyntaxValidation/SyntaxValidationFunctions.cs @@ -4,9 +4,9 @@ namespace Px.Utils.Validation.SyntaxValidation { - public delegate ValidationFeedbackItem? EntryValidationFunction(ValidationEntry validationObject, PxFileSyntaxConf syntaxConf); - public delegate ValidationFeedbackItem? KeyValuePairValidationFunction(ValidationKeyValuePair validationObject, PxFileSyntaxConf syntaxConf); - public delegate ValidationFeedbackItem? StructuredValidationFunction(ValidationStructuredEntry validationObject, PxFileSyntaxConf syntaxConf); + public delegate KeyValuePair? EntryValidationFunction(ValidationEntry validationObject, PxFileSyntaxConf syntaxConf); + public delegate KeyValuePair? KeyValuePairValidationFunction(ValidationKeyValuePair validationObject, PxFileSyntaxConf syntaxConf); + public delegate KeyValuePair? StructuredValidationFunction(ValidationStructuredEntry validationObject, PxFileSyntaxConf syntaxConf); /// /// Contains the default validation functions for syntax validation. @@ -65,8 +65,8 @@ public SyntaxValidationFunctions() /// /// The entry to validate. /// The syntax configuration for the PX file. - /// A if the entry does not start with a line separator, null otherwise. - public static ValidationFeedbackItem? MultipleEntriesOnLine (ValidationEntry validationEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the entry does not start with a line separator, null otherwise. + public static KeyValuePair? MultipleEntriesOnLine (ValidationEntry validationEntry, PxFileSyntaxConf syntaxConf) { // If the entry does not start with a line separator, it is not on its own line. For the first entry this is not relevant. if ( @@ -83,12 +83,13 @@ public SyntaxValidationFunctions() 0, validationEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationEntry, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.MultipleEntriesOnOneLine, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.MultipleEntriesOnOneLine), + new(validationEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value - )); + feedbackIndexes.Value) + ); } } @@ -97,8 +98,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the key contains more than one language parameter, null otherwise. - public static ValidationFeedbackItem? MoreThanOneLanguageParameter(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the key contains more than one language parameter, null otherwise. + public static KeyValuePair? MoreThanOneLanguageParameter(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { ExtractSectionResult languageSections = SyntaxValidationUtilityMethods.ExtractSectionFromString( validationKeyValuePair.KeyValuePair.Key, @@ -113,12 +114,13 @@ public SyntaxValidationFunctions() languageSections.StartIndexes[1], validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MoreThanOneLanguageParameterSection, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MoreThanOneLanguageParameterSection), + new(validationKeyValuePair.File, lineAndCharacter.Key, - lineAndCharacter.Value - )); + lineAndCharacter.Value) + ); } else { @@ -131,8 +133,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the key contains more than one specifier parameter, null otherwise. - public static ValidationFeedbackItem? MoreThanOneSpecifierParameter(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the key contains more than one specifier parameter, null otherwise. + public static KeyValuePair? MoreThanOneSpecifierParameter(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { ExtractSectionResult specifierSpections = SyntaxValidationUtilityMethods.ExtractSectionFromString( validationKeyValuePair.KeyValuePair.Key, @@ -147,12 +149,13 @@ public SyntaxValidationFunctions() specifierSpections.StartIndexes[1], validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MoreThanOneSpecifierParameterSection, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MoreThanOneSpecifierParameterSection), + new(validationKeyValuePair.File, lineAndCharacter.Key, - lineAndCharacter.Value - )); + lineAndCharacter.Value) + ); } else { @@ -165,8 +168,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the key is not defined in the order of KEYWORD[language](\"specifier\"), null otherwise. - public static ValidationFeedbackItem? WrongKeyOrderOrMissingKeyword(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the key is not defined in the order of KEYWORD[language](\"specifier\"), null otherwise. + public static KeyValuePair? WrongKeyOrderOrMissingKeyword(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { string key = validationKeyValuePair.KeyValuePair.Key; @@ -194,11 +197,13 @@ public SyntaxValidationFunctions() 0, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.MissingKeyword, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.MissingKeyword), + new(validationKeyValuePair.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } // Check where language and parameter sections start @@ -220,12 +225,13 @@ public SyntaxValidationFunctions() validationKeyValuePair.LineChangeIndexes ); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.KeyHasWrongOrder, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.KeyHasWrongOrder), + new(validationKeyValuePair.File, specifierIndexes.Key, - specifierIndexes.Value - )); + specifierIndexes.Value) + ); } // Check if the key starts with a language or specifier parameter section else if ( @@ -238,12 +244,13 @@ public SyntaxValidationFunctions() validationKeyValuePair.LineChangeIndexes ); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.KeyHasWrongOrder, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.KeyHasWrongOrder), + new(validationKeyValuePair.File, feedbackIndexes.Key, - feedbackIndexes.Value - )); + feedbackIndexes.Value) + ); } else { @@ -256,8 +263,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if more than two specifiers are found, null otherwise. - public static ValidationFeedbackItem? MoreThanTwoSpecifierParts(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if more than two specifiers are found, null otherwise. + public static KeyValuePair? MoreThanTwoSpecifierParts(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { ExtractSectionResult specifierSection = SyntaxValidationUtilityMethods.ExtractSectionFromString( validationKeyValuePair.KeyValuePair.Key, @@ -289,12 +296,13 @@ public SyntaxValidationFunctions() validationKeyValuePair.LineChangeIndexes ); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.TooManySpecifiers, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.TooManySpecifiers), + new(validationKeyValuePair.File, secondSpecifierIndexes.Key, - secondSpecifierIndexes.Value - )); + secondSpecifierIndexes.Value) + ); } return null; } @@ -304,8 +312,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if there is no delimeter between specifier parts, null otherwise. - public static ValidationFeedbackItem? NoDelimiterBetweenSpecifierParts(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if there is no delimeter between specifier parts, null otherwise. + public static KeyValuePair? NoDelimiterBetweenSpecifierParts(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { ExtractSectionResult specifierSection = SyntaxValidationUtilityMethods.ExtractSectionFromString( validationKeyValuePair.KeyValuePair.Key, @@ -339,11 +347,13 @@ public SyntaxValidationFunctions() specifierSection.StartIndexes[0] + specifierResult.StartIndexes[1], validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.SpecifierDelimiterMissing, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.SpecifierDelimiterMissing), + new(validationKeyValuePair.File, specifierIndexes.Key, - specifierIndexes.Value)); + specifierIndexes.Value) + ); } else { @@ -356,8 +366,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if specifier parts are not enclosed, null otherwise. - public static ValidationFeedbackItem? SpecifierPartNotEnclosed(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if specifier parts are not enclosed, null otherwise. + public static KeyValuePair? SpecifierPartNotEnclosed(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { ExtractSectionResult specifierSection = SyntaxValidationUtilityMethods.ExtractSectionFromString( validationKeyValuePair.KeyValuePair.Key, @@ -387,12 +397,13 @@ public SyntaxValidationFunctions() validationKeyValuePair.LineChangeIndexes ); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.SpecifierPartNotEnclosed, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.SpecifierPartNotEnclosed), + new(validationKeyValuePair.File, specifierIndexes.Key, - specifierIndexes.Value - )); + specifierIndexes.Value) + ); } } return null; @@ -403,8 +414,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the key language section contains illegal symbols, null otherwise. - public static ValidationFeedbackItem? IllegalSymbolsInLanguageParamSection(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the key language section contains illegal symbols, null otherwise. + public static KeyValuePair? IllegalSymbolsInLanguageParamSection(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { string key = validationKeyValuePair.KeyValuePair.Key; @@ -442,12 +453,16 @@ public SyntaxValidationFunctions() languageParam.StartIndexes[0] + indexOfFirstIllegalSymbol, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalCharactersInLanguageParameter, + + + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalCharactersInLanguageParameter), + new(validationKeyValuePair.File, feedbackIndexes.Key, feedbackIndexes.Value, - foundSymbols)); + foundSymbols) + ); } else { @@ -460,8 +475,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the key specifier section contains illegal symbols, null otherwise. - public static ValidationFeedbackItem? IllegalSymbolsInSpecifierParamSection(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the key specifier section contains illegal symbols, null otherwise. + public static KeyValuePair? IllegalSymbolsInSpecifierParamSection(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { string key = validationKeyValuePair.KeyValuePair.Key; @@ -495,12 +510,14 @@ public SyntaxValidationFunctions() specifierParam.StartIndexes[0] + indexOfFirstIllegalSymbol, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalCharactersInSpecifierParameter, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalCharactersInSpecifierParameter), + new(validationKeyValuePair.File, feedbackIndexes.Key, feedbackIndexes.Value, - foundSymbols)); + foundSymbols) + ); } else { @@ -513,8 +530,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the value section is not following a valid format, null otherwise. - public static ValidationFeedbackItem? InvalidValueFormat(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the value section is not following a valid format, null otherwise. + public static KeyValuePair? InvalidValueFormat(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { string value = validationKeyValuePair.KeyValuePair.Value; @@ -528,12 +545,14 @@ public SyntaxValidationFunctions() validationKeyValuePair.ValueStartIndex, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.InvalidValueFormat, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.InvalidValueFormat), + new(validationKeyValuePair.File, feedbackIndexes.Key, feedbackIndexes.Value, - value)); + value) + ); } // If value is of type String or ListOfStrings, check if the line changes are compliant to the specification @@ -547,12 +566,14 @@ public SyntaxValidationFunctions() lineChangeValidityIndex, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.InvalidValueFormat, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.InvalidValueFormat), + new(validationKeyValuePair.File, feedbackIndexes.Key, feedbackIndexes.Value, - value)); + value) + ); } } return null; @@ -563,8 +584,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the value section contains excess whitespace, null otherwise. - public static ValidationFeedbackItem? ExcessWhitespaceInValue(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the value section contains excess whitespace, null otherwise. + public static KeyValuePair? ExcessWhitespaceInValue(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { // Validation only matters if the value is a list of strings if (!SyntaxValidationUtilityMethods.IsStringListFormat( @@ -591,13 +612,15 @@ public SyntaxValidationFunctions() validationKeyValuePair.KeyStartLineIndex, validationKeyValuePair.ValueStartIndex + firstExcessWhitespaceIndex, validationKeyValuePair.LineChangeIndexes); - - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.ExcessWhitespaceInValue, + + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.ExcessWhitespaceInValue), + new(validationKeyValuePair.File, feedbackIndexes.Key, feedbackIndexes.Value, - value)); + value) + ); } return null; @@ -608,8 +631,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the key contains excess whitespace, null otherwise. - public static ValidationFeedbackItem? KeyContainsExcessWhiteSpace(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the key contains excess whitespace, null otherwise. + public static KeyValuePair? KeyContainsExcessWhiteSpace(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { string key = validationKeyValuePair.KeyValuePair.Key; bool insideString = false; @@ -640,12 +663,13 @@ public SyntaxValidationFunctions() i, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.KeyContainsExcessWhiteSpace, + return new KeyValuePair( + new( ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.KeyContainsExcessWhiteSpace), + new(validationKeyValuePair.File, feedbackIndexes.Key, - feedbackIndexes.Value - )); + feedbackIndexes.Value) + ); } // Only expected whitespace outside string sections within key is between specifier parts, after list separator @@ -656,12 +680,13 @@ public SyntaxValidationFunctions() i, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.KeyContainsExcessWhiteSpace, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.KeyContainsExcessWhiteSpace), + new(validationKeyValuePair.File, feedbackIndexes.Key, - feedbackIndexes.Value - )); + feedbackIndexes.Value) + ); } } i++; @@ -674,8 +699,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the value section contains excess new lines, null otherwise. - public static ValidationFeedbackItem? ExcessNewLinesInValue(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the value section contains excess new lines, null otherwise. + public static KeyValuePair? ExcessNewLinesInValue(ValidationKeyValuePair validationKeyValuePair, PxFileSyntaxConf syntaxConf) { // We only need to run this validation if the value is less than 150 characters long and it is a string or list ValueType? type = SyntaxValidationUtilityMethods.GetValueTypeFromString(validationKeyValuePair.KeyValuePair.Value, syntaxConf); @@ -705,11 +730,13 @@ public SyntaxValidationFunctions() validationKeyValuePair.ValueStartIndex + firstNewLineIndex, validationKeyValuePair.LineChangeIndexes); - return new ValidationFeedbackItem(validationKeyValuePair, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.ExcessNewLinesInValue, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.ExcessNewLinesInValue), + new(validationKeyValuePair.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } else { @@ -722,8 +749,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the specifier contains illegal characters, null otherwise. - public static ValidationFeedbackItem? KeywordContainsIllegalCharacters(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the specifier contains illegal characters, null otherwise. + public static KeyValuePair? KeywordContainsIllegalCharacters(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { string keyword = validationStructuredEntry.Key.Keyword; // Missing specifier is catched earlier @@ -744,12 +771,14 @@ public SyntaxValidationFunctions() keyword.IndexOf(illegalSymbolsInKeyWord.First(), StringComparison.Ordinal), validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalCharactersInKeyword, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalCharactersInKeyword), + new(validationStructuredEntry.File, feedbackIndexes.Key, feedbackIndexes.Value, - string.Join(", ", illegalSymbolsInKeyWord))); + string.Join(", ", illegalSymbolsInKeyWord)) + ); } } catch (RegexMatchTimeoutException) @@ -759,11 +788,13 @@ public SyntaxValidationFunctions() 0, validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.RegexTimeout, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.RegexTimeout), + new(validationStructuredEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } return null; @@ -774,8 +805,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the specifier doesn't start with a letter, null otherwise. - public static ValidationFeedbackItem? KeywordDoesntStartWithALetter(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the specifier doesn't start with a letter, null otherwise. + public static KeyValuePair? KeywordDoesntStartWithALetter(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { string keyword = validationStructuredEntry.Key.Keyword; @@ -787,12 +818,13 @@ public SyntaxValidationFunctions() 0, validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.KeywordDoesntStartWithALetter, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.KeywordDoesntStartWithALetter), + new(validationStructuredEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value - )); + feedbackIndexes.Value) + ); } else { @@ -805,8 +837,10 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the language parameter is not following a valid format, null otherwise. - public static ValidationFeedbackItem? IllegalCharactersInLanguageParameter(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the language parameter is not following a valid format, null otherwise. + public static KeyValuePair? IllegalCharactersInLanguageParameter( + ValidationStructuredEntry validationStructuredEntry, + PxFileSyntaxConf syntaxConf) { // Running this validation is relevant only for objects with a language parameter if (validationStructuredEntry.Key.Language is null) @@ -840,12 +874,15 @@ public SyntaxValidationFunctions() validationStructuredEntry.LineChangeIndexes); string foundSymbols = string.Join(", ", foundIllegalCharacters); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalCharactersInLanguageParameter, + + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalCharactersInLanguageParameter), + new(validationStructuredEntry.File, feedbackIndexes.Key, feedbackIndexes.Value, - foundSymbols)); + foundSymbols) + ); } else { @@ -858,8 +895,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the specifier parameter is not following a valid format, null otherwise. - public static ValidationFeedbackItem? IllegalCharactersInSpecifierParts(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the specifier parameter is not following a valid format, null otherwise. + public static KeyValuePair? IllegalCharactersInSpecifierParts(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { // Running this validation is relevant only for objects with a specifier if (validationStructuredEntry.Key.FirstSpecifier is null) @@ -885,12 +922,15 @@ public SyntaxValidationFunctions() validationStructuredEntry.LineChangeIndexes); char[] characters = [..illegalcharactersInFirstSpecifier, ..illegalcharactersInSecondSpecifier]; - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.IllegalCharactersInSpecifierPart, + + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.IllegalCharactersInSpecifierPart), + new(validationStructuredEntry.File, feedbackIndexes.Key, feedbackIndexes.Value, - string.Join(", ", characters))); + string.Join(", ", characters)) + ); } else { @@ -903,8 +943,8 @@ public SyntaxValidationFunctions() /// /// The validationKeyValuePair to validate. /// The syntax configuration for the PX file. - /// A if there is no value section, null otherwise. - public static ValidationFeedbackItem? EntryWithoutValue(ValidationEntry validationEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if there is no value section, null otherwise. + public static KeyValuePair? EntryWithoutValue(ValidationEntry validationEntry, PxFileSyntaxConf syntaxConf) { int[] keywordSeparatorIndeces = SyntaxValidationUtilityMethods.FindKeywordSeparatorIndeces(validationEntry.EntryString, syntaxConf); @@ -915,11 +955,13 @@ public SyntaxValidationFunctions() validationEntry.EntryString.Length, validationEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.EntryWithoutValue, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.EntryWithoutValue), + new(validationEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } else if (keywordSeparatorIndeces.Length > 1) { @@ -928,11 +970,13 @@ public SyntaxValidationFunctions() keywordSeparatorIndeces[1], validationEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationEntry, new ValidationFeedback( - ValidationFeedbackLevel.Error, - ValidationFeedbackRule.EntryWithMultipleValues, + return new KeyValuePair( + new(ValidationFeedbackLevel.Error, + ValidationFeedbackRule.EntryWithMultipleValues), + new(validationEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } else { @@ -945,8 +989,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the language parameter is not compliant with ISO 639 or BCP 47, null otherwise. - public static ValidationFeedbackItem? IncompliantLanguage (ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the language parameter is not compliant with ISO 639 or BCP 47, null otherwise. + public static KeyValuePair? IncompliantLanguage (ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { // Running this validation is relevant only for objects with a language if (validationStructuredEntry.Key.Language is null) @@ -970,12 +1014,13 @@ public SyntaxValidationFunctions() validationStructuredEntry.Key.Keyword.Length + 1, validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.IncompliantLanguage, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.IncompliantLanguage), + new(validationStructuredEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value - )); + feedbackIndexes.Value) + ); } } @@ -984,8 +1029,8 @@ public SyntaxValidationFunctions() /// /// The to validate. /// The syntax configuration for the PX file. - /// A if the specifier contains unrecommended characters, null otherwise. - public static ValidationFeedbackItem? KeywordContainsUnderscore (ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the specifier contains unrecommended characters, null otherwise. + public static KeyValuePair? KeywordContainsUnderscore (ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { int underscoreIndex = validationStructuredEntry.Key.Keyword.IndexOf('_'); if (underscoreIndex != -1) @@ -995,11 +1040,13 @@ public SyntaxValidationFunctions() underscoreIndex, validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.KeywordContainsUnderscore, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.KeywordContainsUnderscore), + new(validationStructuredEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } else { @@ -1012,8 +1059,8 @@ public SyntaxValidationFunctions() /// /// The to validate /// The syntax configuration for the PX file. - /// A if the specifier is not in upper case, otherwise null - public static ValidationFeedbackItem? KeywordIsNotInUpperCase(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the specifier is not in upper case, otherwise null + public static KeyValuePair? KeywordIsNotInUpperCase(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { string keyword = validationStructuredEntry.Key.Keyword; string uppercaseKeyword = keyword.ToUpper(CultureInfo.InvariantCulture); @@ -1025,11 +1072,13 @@ public SyntaxValidationFunctions() 0, validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.KeywordIsNotInUpperCase, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.KeywordIsNotInUpperCase), + new(validationStructuredEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } else { @@ -1042,8 +1091,8 @@ public SyntaxValidationFunctions() /// /// The object to validate /// The syntax configuration for the PX file. - /// A if the specifier is excessively long, otherwise null - public static ValidationFeedbackItem? KeywordIsExcessivelyLong(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) + /// A validation feedback key value pair if the specifier is excessively long, otherwise null + public static KeyValuePair? KeywordIsExcessivelyLong(ValidationStructuredEntry validationStructuredEntry, PxFileSyntaxConf syntaxConf) { const int keywordLengthRecommendedLimit = 20; string keyword = validationStructuredEntry.Key.Keyword; @@ -1055,11 +1104,13 @@ public SyntaxValidationFunctions() keyword.Length, validationStructuredEntry.LineChangeIndexes); - return new ValidationFeedbackItem(validationStructuredEntry, new ValidationFeedback( - ValidationFeedbackLevel.Warning, - ValidationFeedbackRule.KeywordExcessivelyLong, + return new KeyValuePair( + new(ValidationFeedbackLevel.Warning, + ValidationFeedbackRule.KeywordExcessivelyLong), + new(validationStructuredEntry.File, feedbackIndexes.Key, - feedbackIndexes.Value)); + feedbackIndexes.Value) + ); } else { diff --git a/Px.Utils/Validation/SyntaxValidation/SyntaxValidationResult.cs b/Px.Utils/Validation/SyntaxValidation/SyntaxValidationResult.cs index 0182489..cbb17da 100644 --- a/Px.Utils/Validation/SyntaxValidation/SyntaxValidationResult.cs +++ b/Px.Utils/Validation/SyntaxValidation/SyntaxValidationResult.cs @@ -3,11 +3,11 @@ /// /// Represents the result of a syntax validation operation. This struct contains a validation report and a list of structured validation entries. /// - /// An array of objects produced by the syntax validation operation. + /// A dictionary of amd objects produced by the syntax validation operation. /// A list of objects produced by the syntax validation operation. /// The row number where the data section starts in the file. /// The stream position where the data section starts in the file. - public class SyntaxValidationResult(ValidationFeedbackItem[] feedbackItems, List result, int dataStartRow, int dataStartStreamPosition) : ValidationResult(feedbackItems) + public class SyntaxValidationResult(ValidationFeedback feedbacks, List result, int dataStartRow, int dataStartStreamPosition) : ValidationResult(feedbacks) { /// /// Gets the list of objects produced by the syntax validation operation. diff --git a/Px.Utils/Validation/SyntaxValidation/SyntaxValidator.cs b/Px.Utils/Validation/SyntaxValidation/SyntaxValidator.cs index 1f28f84..d25a7eb 100644 --- a/Px.Utils/Validation/SyntaxValidation/SyntaxValidator.cs +++ b/Px.Utils/Validation/SyntaxValidation/SyntaxValidator.cs @@ -31,7 +31,7 @@ public class SyntaxValidator( /// Validates the syntax of a PX file's metadata. /// /// A entry which contains a list of entries - /// and a list of entries accumulated during the validation. + /// and a dictionary of type accumulated during the validation. public SyntaxValidationResult Validate() { SyntaxValidationFunctions validationFunctions = new(); @@ -48,23 +48,23 @@ public SyntaxValidationResult Validate() syntaxConf ??= PxFileSyntaxConf.Default; - List validationFeedback = []; + ValidationFeedback validationFeedbacks = []; List stringEntries = BuildValidationEntries(stream, encoding, syntaxConf, filename, _bufferSize); - validationFeedback.AddRange(ValidateEntries(stringEntries, stringValidationFunctions, syntaxConf)); + validationFeedbacks.AddRange(ValidateEntries(stringEntries, stringValidationFunctions, syntaxConf)); List keyValuePairs = BuildKeyValuePairs(stringEntries, syntaxConf); - validationFeedback.AddRange(ValidateKeyValuePairs(keyValuePairs, keyValueValidationFunctions, syntaxConf)); + validationFeedbacks.AddRange(ValidateKeyValuePairs(keyValuePairs, keyValueValidationFunctions, syntaxConf)); List structuredEntries = BuildValidationStructureEntries(keyValuePairs, syntaxConf); - validationFeedback.AddRange(ValidateStructs(structuredEntries, structuredValidationFunctions, syntaxConf)); + validationFeedbacks.AddRange(ValidateStructs(structuredEntries, structuredValidationFunctions, syntaxConf)); - return new SyntaxValidationResult([.. validationFeedback], structuredEntries, _dataSectionStartRow, _dataSectionStartStreamPosition); + return new SyntaxValidationResult(validationFeedbacks, structuredEntries, _dataSectionStartRow, _dataSectionStartStreamPosition); } /// /// Asynchronously validates the syntax of a PX file's metadata. /// /// An optional parameter that can be used to cancel the operation. - /// A task that contains a entry, which contains the structured validation entries - /// and a list of entries accumulated during the validation. + /// A task that contains a entry which contains a list of entries + /// and a dictionary of type accumulated during the validation. public async Task ValidateAsync(CancellationToken cancellationToken = default) { SyntaxValidationFunctions validationFunctions = new(); @@ -80,15 +80,15 @@ public async Task ValidateAsync(CancellationToken cancel } syntaxConf ??= PxFileSyntaxConf.Default; - List validationFeedback = []; + ValidationFeedback validationFeedbacks = []; List entries = await BuildValidationEntriesAsync(stream, encoding, syntaxConf, filename, _bufferSize, cancellationToken); - validationFeedback.AddRange(ValidateEntries(entries, stringValidationFunctions, syntaxConf)); + validationFeedbacks.AddRange(ValidateEntries(entries, stringValidationFunctions, syntaxConf)); List keyValuePairs = BuildKeyValuePairs(entries, syntaxConf); - validationFeedback.AddRange(ValidateKeyValuePairs(keyValuePairs, keyValueValidationFunctions, syntaxConf)); + validationFeedbacks.AddRange(ValidateKeyValuePairs(keyValuePairs, keyValueValidationFunctions, syntaxConf)); List structuredEntries = BuildValidationStructureEntries(keyValuePairs, syntaxConf); - validationFeedback.AddRange(ValidateStructs(structuredEntries, structuredValidationFunctions, syntaxConf)); + validationFeedbacks.AddRange(ValidateStructs(structuredEntries, structuredValidationFunctions, syntaxConf)); - return new SyntaxValidationResult([.. validationFeedback], structuredEntries, _dataSectionStartRow, _dataSectionStartStreamPosition); + return new SyntaxValidationResult(validationFeedbacks, structuredEntries, _dataSectionStartRow, _dataSectionStartStreamPosition); } /// @@ -121,57 +121,57 @@ async Task IPxFileValidatorAsync.ValidateAsync(CancellationTok #endregion - private static List ValidateEntries(IEnumerable entries, IEnumerable validationFunctions, PxFileSyntaxConf syntaxConf) + private static ValidationFeedback ValidateEntries(IEnumerable entries, IEnumerable validationFunctions, PxFileSyntaxConf syntaxConf) { - List validationFeedback = []; + ValidationFeedback validationFeedback = []; foreach (ValidationEntry entry in entries) { foreach (EntryValidationFunction function in validationFunctions) { - ValidationFeedbackItem? feedback = function(entry, syntaxConf); + KeyValuePair? feedback = function(entry, syntaxConf); if (feedback is not null) { - validationFeedback.Add((ValidationFeedbackItem)feedback); + validationFeedback.Add((KeyValuePair )feedback); } } } return validationFeedback; } - private static List ValidateKeyValuePairs( + private static ValidationFeedback ValidateKeyValuePairs( IEnumerable kvpObjects, IEnumerable validationFunctions, PxFileSyntaxConf syntaxConf) { - List validationFeedback = []; + ValidationFeedback validationFeedback = []; foreach (ValidationKeyValuePair kvpObject in kvpObjects) { foreach (KeyValuePairValidationFunction function in validationFunctions) { - ValidationFeedbackItem? feedback = function(kvpObject, syntaxConf); + KeyValuePair? feedback = function(kvpObject, syntaxConf); if (feedback is not null) { - validationFeedback.Add((ValidationFeedbackItem)feedback); + validationFeedback.Add((KeyValuePair)feedback); } } } return validationFeedback; } - private static List ValidateStructs( + private static ValidationFeedback ValidateStructs( IEnumerable structuredEntries, IEnumerable validationFunctions, PxFileSyntaxConf syntaxConf) { - List validationFeedback = []; + ValidationFeedback validationFeedback = []; foreach (ValidationStructuredEntry structuredEntry in structuredEntries) { foreach (StructuredValidationFunction function in validationFunctions) { - ValidationFeedbackItem? feedback = function(structuredEntry, syntaxConf); + KeyValuePair? feedback = function(structuredEntry, syntaxConf); if (feedback is not null) { - validationFeedback.Add((ValidationFeedbackItem)feedback); + validationFeedback.Add((KeyValuePair)feedback); } } } diff --git a/Px.Utils/Validation/ValidationFeedback.cs b/Px.Utils/Validation/ValidationFeedback.cs index 24232b5..d9cde7e 100644 --- a/Px.Utils/Validation/ValidationFeedback.cs +++ b/Px.Utils/Validation/ValidationFeedback.cs @@ -1,9 +1,54 @@ -namespace Px.Utils.Validation +using System.Collections.Concurrent; + +namespace Px.Utils.Validation { /// - /// Validation feedback represents the result of a validation operation. + /// Represents the result of a validation operation. Associates feedback levels and rules with instances of violations. + /// + public class ValidationFeedback() : ConcurrentDictionary> + { + /// + /// Adds a feedback item to the feedback dictionary. + /// + public void Add(KeyValuePair item) + { + if (!ContainsKey(item.Key)) + { + this[item.Key] = []; + } + this[item.Key].Add(item.Value); + } + + /// + /// Adds multiple feedback items to the feedback dictionary. + /// + /// Feedback key value pairs to add + public void AddRange(ConcurrentDictionary> feedbacks) + { + foreach (KeyValuePair> kvp in feedbacks) + { + if (!ContainsKey(kvp.Key)) + { + this[kvp.Key] = []; + } + this[kvp.Key].AddRange(kvp.Value); + } + } + + /// + /// Constructor that initializes the feedback dictionary with a single feedback item. + /// + /// Feedback key value pair to add + public ValidationFeedback(KeyValuePair item) : this() + { + Add(item); + } + } + + /// + /// Validation feedback contains information about validation errors or warnings that occurred during validation. /// - public readonly struct ValidationFeedback(ValidationFeedbackLevel level, ValidationFeedbackRule rule, int line = 0, int character = 0, string? additionalInfo = null) + public readonly struct ValidationFeedbackKey(ValidationFeedbackLevel level, ValidationFeedbackRule rule) { /// /// Enum that gets the level of the feedback. This can be used to categorize feedback items by severity. @@ -14,19 +59,27 @@ public readonly struct ValidationFeedback(ValidationFeedbackLevel level, Validat /// Enum that defines the type of validation feedback rule. Can be used to categorize feedback by rule type or for translations. /// public ValidationFeedbackRule Rule { get; } = rule; + } + /// + /// Stores information about a specific instance of a validation feedback rule violation. + /// + public readonly struct ValidationFeedbackValue(string filename, int line = 0, int character = 0, string? additionalInfo = null) + { + /// + /// Name of the file where the violation occurred. + /// + public string Filename { get; } = filename; /// - /// Index of the line the feedback is associated with. + /// Line number where the violation occurred. /// public int Line { get; } = line; - /// - /// Index of the character where the issue related to the feedback starts. + /// Character position where the violation occurred. /// public int Character { get; } = character; - /// - /// Any additional information can be stored into this property. + /// Additional information about the violation. /// public string? AdditionalInfo { get; } = additionalInfo; } diff --git a/Px.Utils/Validation/ValidationFeedbackItem.cs b/Px.Utils/Validation/ValidationFeedbackItem.cs deleted file mode 100644 index 4a1ab9a..0000000 --- a/Px.Utils/Validation/ValidationFeedbackItem.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Px.Utils.Validation -{ - /// - /// A validation feedback item associates a with the feedback from validating that object. - /// - /// The that this feedback item is associated with. - /// The from validating the object. - public readonly struct ValidationFeedbackItem(ValidationObject validationObject, ValidationFeedback feedback) - { - - /// - /// Gets the that this feedback item is associated with. - /// - public ValidationObject ValidationObject { get; } = validationObject; - - - /// - /// Gets the from validating the ValidationObject. - /// - public ValidationFeedback Feedback { get; } = feedback; - } -} diff --git a/Px.Utils/Validation/ValidationObject.cs b/Px.Utils/Validation/ValidationObject.cs index 63bab6b..893d6e9 100644 --- a/Px.Utils/Validation/ValidationObject.cs +++ b/Px.Utils/Validation/ValidationObject.cs @@ -16,7 +16,7 @@ public class ValidationObject(string file, int keyStartLineIndex, int[] lineChan public int KeyStartLineIndex { get; } = keyStartLineIndex; /// - /// Character indexes of the line changes in the entry starting from the entry start- + /// Character indexes of the line changes in the entry starting from the entry start. /// public int[] LineChangeIndexes { get; } = lineChangeIndexes; }