diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..2adf293 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,70 @@ +# Правила для GitHub Copilot + +- Всегда отвечай, используя русский язык +- Всегда пиши комментарии в коде на русском языке + +## Комментарии +- Короткие пояснительные комментарии располагай в конце той же строки, что и код // кратко по делу +- Старайся избегать тривиальных комментариев + +## XML‑документация +- Документируй классы, структуры, делегаты, перечисления и их члены только XML‑комментариями +- Одинарное предложение пиши в одной строке внутри тега и без точки в конце +- Каждый тег XML‑комментария располагай на отдельной строке +- Порядок тегов: `` → `` → `` → `` → `` → `` +- Для сложных публичных метдов генерируй блок с простым примером использования кода внутри тега `` + +Примеры: +- `Краткое описание сущности` +- `Описание параметра` +- `Описание возвращаемого значения` + +## Синтаксис и минимализм +- При генерации кода используй современные конструкции языка, совместимые с целевыми платформами проекта +- Стремись минимизировать количество фигурных скобок за счёт expression‑bodied членов и switch‑выражений +- Не убирай фигурные скобки в многострочных конструкциях ради читаемости +- Всегда старайся минимизировать размер кода, если не запрошено иное + +Разрешённые современные приёмы (когда поддерживается целевой платформой): +- file‑scoped namespace +- expression‑bodied члены +- switch‑выражения и pattern matching +- target‑typed `new` +- collection expressions и инициализаторы коллекций +- `using var` и `await using` +- операторы `??`, `??=`, `is not`, `with` +- упрощение nullable-присвоения `target?.Property = 15;` вместо `if(target is not null) target.Property = 15;` + +## Именование +- Локальные переменные: `snake_case` +- Параметры методов: `PascalCase` +- Поля экземпляров: `_PascalCase` +- Статические поля: `__PascalCase` +- Константы: `PascalCase` +- Публичные типы и члены API: `PascalCase` +- Предпочитай английский язык при именовании переменных, методов, классов и прочих сущностей + +## Инициализация и объявления +- При инициализации массивов, списков и словарей используй выражения инициализации массивов/коллекций +- При объявлении переменных предпочитай использовать ключевое слово `var` (кроме случаев, когда явный тип заметно повышает понятность) + +## Форматирование +- Короткие системные комментарии пиши компактно в одну строку +- Удаляй неиспользуемые `using`, сортируй и группируй директивы `using` +- Разделяй логические блоки пустыми строками по мере необходимости, избегай лишних переносов + +## Практики .NET +- Включай `#nullable enable` там, где это поддерживается +- Используй guard‑выражения, например `ArgumentNullException.ThrowIfNull(x)` +- Предпочитай Try‑паттерны для контроля потока вместо исключений +- При генерации метода добавляй в его начале блок проверки входных параметров. Отделяй этот блок пустой строкой от остального тела метода +- При генерации публичных свойств у моделей-представления MVVM (классов, реализующих INotifyPropertyChanged) используй следующий формат (в одну строку): +```csharp +/// Описание свойства +public string PropertyName { get; set => Set(ref field, value); } +``` +- Для простых лаконичных методов используй expression‑bodied синтаксис, записанный в одну строку. + +## Совместимость целей +- В рабочем пространстве используются целевые платформы: `.NET Standard 2.0` и `.NET 10` +- Применяй современные возможности языка и платформы только если они доступны для соответствующей целевой платформы проекта \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 24d9efd..c6c7f9c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,7 +23,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 10.0.x - name: Cache NuGet uses: actions/cache@v3 @@ -61,10 +61,10 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 10.0.x - name: Get artifact - uses: actions/download-artifact@v3.0.1 + uses: actions/download-artifact@v4.1.7 id: download with: name: Release @@ -82,10 +82,10 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 10.0.x - name: Get artifact - uses: actions/download-artifact@v3.0.1 + uses: actions/download-artifact@v4.1.7 id: download with: name: Release diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 1d8fca8..26dc348 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -19,7 +19,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 10.0.x - name: Building run: dotnet build -c Debug diff --git a/MathCore.TestsExtensions.sln b/MathCore.TestsExtensions.sln index d5027d4..39a844d 100644 --- a/MathCore.TestsExtensions.sln +++ b/MathCore.TestsExtensions.sln @@ -1,12 +1,28 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.4.33103.184 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11205.157 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MathCore.TestsExtensions", "MathCore.TestsExtensions\MathCore.TestsExtensions.csproj", "{0F039156-E6CB-4EFB-A863-13A1AC2DD4AE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MathCore.TestsExtensions.Tests", "Tests\MathCore.TestsExtensions.Tests\MathCore.TestsExtensions.Tests.csproj", "{10093BD2-D872-4383-B075-92850E009647}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Service", ".Service", "{29B29638-89EC-4383-B587-AE8C981DED4F}" + ProjectSection(SolutionItems) = preProject + .github\copilot-instructions.md = .github\copilot-instructions.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{D6A23A02-D860-4101-AB7B-0C7FB57331CB}" + ProjectSection(SolutionItems) = preProject + .github\copilot-instructions.md = .github\copilot-instructions.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{83B95A2F-1D99-43CB-BA0C-769D88078D6F}" + ProjectSection(SolutionItems) = preProject + .github\workflows\publish.yml = .github\workflows\publish.yml + .github\workflows\testing.yml = .github\workflows\testing.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,6 +41,10 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D6A23A02-D860-4101-AB7B-0C7FB57331CB} = {29B29638-89EC-4383-B587-AE8C981DED4F} + {83B95A2F-1D99-43CB-BA0C-769D88078D6F} = {D6A23A02-D860-4101-AB7B-0C7FB57331CB} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5C7C0D00-B422-4B19-B6D4-19B55F78389C} EndGlobalSection diff --git a/MathCore.TestsExtensions/Accuracy.cs b/MathCore.TestsExtensions/Accuracy.cs index 71cb254..6c28fe8 100644 --- a/MathCore.TestsExtensions/Accuracy.cs +++ b/MathCore.TestsExtensions/Accuracy.cs @@ -1,18 +1,51 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; +/// Утилиты для создания сравнителей точности и пользовательских сравнителей/проверок равенства public static class Accuracy { + /// Создаёт сравнитель чисел типа с заданной абсолютной точностью + /// Допустимое отклонение (ε). Должно быть неотрицательным и не NaN + /// Экземпляр и + /// Если < 0 + /// Если равен public static IEqualityComparer Eps(double eps) => new AccuracyComparer(eps); + + /// Создаёт сравнитель целых чисел типа с заданной абсолютной точностью + /// Допустимое отклонение (ε). Должно быть неотрицательным + /// Экземпляр и + /// Если < 0 public static IEqualityComparer Eps(int eps) => new AccuracyComparer(eps); - public static IEqualityComparer Equals(Func Comparer, Func Hasher) => new AccuracyEqualityComparer(Comparer, Hasher); - public static IComparer Compare(Comparison Comparer) => new AccuracyComparer(Comparer); + /// Создаёт универсальный сравнитель равенства на основе делегатов + /// Тип сравниваемых объектов + /// Делегат, выполняющий проверку равенства + /// Делегат, вычисляющий хеш-код + /// использующий предоставленные делегаты + /// Если один из делегатов равен null + public static IEqualityComparer Equals(Func Comparer, Func Hasher) => + new AccuracyEqualityComparer(Comparer ?? throw new ArgumentNullException(nameof(Comparer)), + Hasher ?? throw new ArgumentNullException(nameof(Hasher))); + + /// Создаёт универсальный сравнитель порядка на основе делегата + /// Тип сравниваемых объектов + /// Делегат сравнения + /// использующий предоставленный делегат + /// Если равен null + public static IComparer Compare(Comparison Comparer) => + new AccuracyComparer(Comparer ?? throw new ArgumentNullException(nameof(Comparer))); } +/// Сравнитель значений типов и с учётом допустимой абсолютной погрешности +/// +/// Для чисел с плавающей точкой равенство определяется условием |x - y| ≤ ε. +/// Для операций хеширования используется нормализация по шагу ε (округление к сетке). +/// +/// Допустимое отклонение (ε). Должно быть неотрицательным public readonly struct AccuracyComparer(double Eps) : IEqualityComparer, IComparer, IEqualityComparer, IComparer { + /// Допустимое абсолютное отклонение private double Eps { get; init; } = Eps switch { < 0 => throw new ArgumentOutOfRangeException(nameof(Eps), Eps, "Значение точности не должно быть меньше нуля"), @@ -20,12 +53,21 @@ public readonly struct AccuracyComparer(double Eps) : _ => Eps }; + /// Проверяет равенство двух значений с учётом точности public bool Equals(double x, double y) => Math.Abs(x - y) <= Eps; - public int GetHashCode(double x) => x is double.NaN - ? x.GetHashCode() + /// Вычисляет хеш-код для значения , нормализуя его относительно точности + /// Значение + /// Хеш-код + public int GetHashCode(double x) => x is double.NaN + ? x.GetHashCode() : (Math.Round(x * Eps) / Eps).GetHashCode(); + /// Сравнивает два значения с учётом допустимой погрешности + /// Первое значение + /// Второе значение + /// 0 если считаются равными; -1 или 1 в зависимости от знака разности + /// Если одно из значений равно public int Compare(double x, double y) { var delta = x - y; @@ -38,15 +80,19 @@ public int Compare(double x, double y) { nameof(y), y }, } }; - return Math.Abs(delta) <= Eps - ? 0 + return Math.Abs(delta) <= Eps + ? 0 : Math.Sign(delta); } + /// Проверяет равенство двух значений с учётом допустимого отклонения public bool Equals(int x, int y) => Math.Abs(x - y) <= Eps; + /// Вычисляет хеш-код для целого значения с учётом нормализации к сетке точности public int GetHashCode(int x) => (Math.Round(x * Eps) / Eps).GetHashCode(); + /// Сравнивает два значения с учётом допустимого отклонения + /// 0 если считаются равными; -1 или 1 в зависимости от знака разности public int Compare(int x, int y) { var delta = x - y; @@ -56,14 +102,24 @@ public int Compare(int x, int y) } } +/// Универсальный сравнитель равенства на основе переданных делегатов +/// Тип сравниваемых объектов +/// Делегат проверки равенства +/// Делегат вычисления хеш-кода public class AccuracyEqualityComparer(Func Comparer, Func Hasher) : IEqualityComparer { + /// Проверяет равенство двух объектов public bool Equals(T x, T y) => Comparer(x, y); + /// Вычисляет хеш-код объекта public int GetHashCode(T obj) => Hasher(obj); } +/// Универсальный сравнитель порядка на основе делегата +/// Тип сравниваемых объектов +/// Делегат сравнения public class AccuracyComparer(Comparison Comparer) : IComparer { + /// Сравнивает два значения public int Compare(T x, T y) => Comparer(x, y); } diff --git a/MathCore.TestsExtensions/Attributes/DataTestMethodIterativeAttribute.cs b/MathCore.TestsExtensions/Attributes/DataTestMethodIterativeAttribute.cs index 1744c08..d8b417d 100644 --- a/MathCore.TestsExtensions/Attributes/DataTestMethodIterativeAttribute.cs +++ b/MathCore.TestsExtensions/Attributes/DataTestMethodIterativeAttribute.cs @@ -2,13 +2,16 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedAutoPropertyAccessor.Global +using System.Runtime.CompilerServices; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Итерационное выполнение теста на основе данных с заданием числа итераций для набора статистики /// Инициализация итерационного теста на основе данных /// Число итераций [AttributeUsage(AttributeTargets.Method)] -public class DataTestMethodIterativeAttribute(int IterationsCount) : TestMethodAttribute +public class DataTestMethodIterativeAttribute(int IterationsCount, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) + : TestMethodAttribute(callerFilePath, callerLineNumber) { /// Число итераций повторения теста private readonly int _IterationsCount = IterationsCount; @@ -17,13 +20,13 @@ public class DataTestMethodIterativeAttribute(int IterationsCount) : TestMethodA public bool StopAtFirstFail { get; set; } /// - public override TestResult[] Execute(ITestMethod TestMethod) + public override async Task ExecuteAsync(ITestMethod TestMethod) { var results = new List(); var stop_at_first_fail = this.StopAtFirstFail; for (var count = 0; count < _IterationsCount; count++) { - var test_results = base.Execute(TestMethod); + var test_results = await base.ExecuteAsync(TestMethod); results.AddRange(test_results); if (stop_at_first_fail && test_results.Any(r => r.TestFailureException != null)) break; } diff --git a/MathCore.TestsExtensions/Attributes/TestClassHandlerAttribute.cs b/MathCore.TestsExtensions/Attributes/TestClassHandlerAttribute.cs index 2ed3d7d..ffe7e9b 100644 --- a/MathCore.TestsExtensions/Attributes/TestClassHandlerAttribute.cs +++ b/MathCore.TestsExtensions/Attributes/TestClassHandlerAttribute.cs @@ -27,6 +27,6 @@ public override TestMethodAttribute GetTestMethodAttribute(TestMethodAttribute A HandlePassed = HandlePassed, }; - return base.GetTestMethodAttribute(Attribute); + return base.GetTestMethodAttribute(Attribute!)!; } } \ No newline at end of file diff --git a/MathCore.TestsExtensions/Attributes/TestClassIterativeAttribute.cs b/MathCore.TestsExtensions/Attributes/TestClassIterativeAttribute.cs index 667ff6b..3d0b90c 100644 --- a/MathCore.TestsExtensions/Attributes/TestClassIterativeAttribute.cs +++ b/MathCore.TestsExtensions/Attributes/TestClassIterativeAttribute.cs @@ -18,7 +18,7 @@ public class TestClassIterativeAttribute(int IterationsCount) : TestClassAttribu public bool StopAtFirstFail { get; set; } /// - public override TestMethodAttribute GetTestMethodAttribute(TestMethodAttribute TestMethodAttribute) + public override TestMethodAttribute GetTestMethodAttribute(TestMethodAttribute? TestMethodAttribute) { var attribute = TestMethodAttribute as TestMethodIterativeAttribute ?? new TestMethodIterativeAttribute(_IterationsCount); attribute.StopAtFirstFail = StopAtFirstFail; diff --git a/MathCore.TestsExtensions/Attributes/TestMethodHandlerAttribute.cs b/MathCore.TestsExtensions/Attributes/TestMethodHandlerAttribute.cs index 21bd72b..8337d09 100644 --- a/MathCore.TestsExtensions/Attributes/TestMethodHandlerAttribute.cs +++ b/MathCore.TestsExtensions/Attributes/TestMethodHandlerAttribute.cs @@ -1,21 +1,22 @@ using System.Reflection; +using System.Runtime.CompilerServices; namespace Microsoft.VisualStudio.TestTools.UnitTesting; [AttributeUsage(AttributeTargets.Method)] -public class TestMethodHandlerAttribute(string? ExceptionHandlerMethod, string? DisplayName = null) - : TestMethodAttribute(DisplayName) +public class TestMethodHandlerAttribute(string? ExceptionHandlerMethod, bool HandlePassed = false, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) : TestMethodAttribute(callerFilePath, callerLineNumber) { - public TestMethodHandlerAttribute() : this(null) { } + public TestMethodHandlerAttribute(bool HandlePassed = false, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) : this(null, HandlePassed, callerFilePath, callerLineNumber) { } public string? ExceptionHandlerMethod { get; set; } = ExceptionHandlerMethod; - public bool HandlePassed { get; set; } + public bool HandlePassed { get; set; } = HandlePassed; - public override TestResult[] Execute(ITestMethod Method) + public override async Task ExecuteAsync(ITestMethod Method) { + if (ExceptionHandlerMethod is not { Length: > 0 } handler_method_name) - return base.Execute(Method); + return await base.ExecuteAsync(Method); var test_class = Method.MethodInfo.DeclaringType ?? throw new InvalidOperationException("Невозможно определить класс модульного теста"); @@ -32,9 +33,9 @@ public override TestResult[] Execute(ITestMethod Method) test_class.GetMethod(handler_method_name, private_static, null, [test_result_type], null); if (handler_method_info is null) - return base.Execute(Method); + return await base.ExecuteAsync(Method); - var result = base.Execute(Method); + var result = await base.ExecuteAsync(Method); var results_to_process = HandlePassed ? result diff --git a/MathCore.TestsExtensions/Attributes/TestMethodIterativeAttribute.cs b/MathCore.TestsExtensions/Attributes/TestMethodIterativeAttribute.cs index 0f8acfd..9ad9e56 100644 --- a/MathCore.TestsExtensions/Attributes/TestMethodIterativeAttribute.cs +++ b/MathCore.TestsExtensions/Attributes/TestMethodIterativeAttribute.cs @@ -1,10 +1,12 @@ -namespace Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Runtime.CompilerServices; + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Итерационное выполнение теста с заданием числа итераций для набора статистики /// Инициализация итерационного теста /// Число итераций [AttributeUsage(AttributeTargets.Method)] -public class TestMethodIterativeAttribute(int IterationsCount) : TestMethodAttribute +public class TestMethodIterativeAttribute(int IterationsCount, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) : TestMethodAttribute(callerFilePath, callerLineNumber) { /// Число итераций повторения теста private readonly int _IterationsCount = IterationsCount; @@ -13,13 +15,13 @@ public class TestMethodIterativeAttribute(int IterationsCount) : TestMethodAttri public bool StopAtFirstFail { get; set; } /// - public override TestResult[] Execute(ITestMethod TestMethod) + public override async Task ExecuteAsync(ITestMethod TestMethod) { var results = new List(); var stop_at_first_fail = StopAtFirstFail; for (var count = 0; count < _IterationsCount; count++) { - var test_results = base.Execute(TestMethod); + var test_results = await base.ExecuteAsync(TestMethod); results.AddRange(test_results); if (stop_at_first_fail && test_results.Any(r => r.TestFailureException != null)) break; } diff --git a/MathCore.TestsExtensions/Checkers/ActionChecker.cs b/MathCore.TestsExtensions/Checkers/ActionChecker.cs index c2b19ae..1eeb4ee 100644 --- a/MathCore.TestsExtensions/Checkers/ActionChecker.cs +++ b/MathCore.TestsExtensions/Checkers/ActionChecker.cs @@ -30,7 +30,7 @@ public ValueChecker Throw(string? Message = null) where { return Assert.That.Value(exception).As("Получено исключение, отличное от ожидаемого"); } - throw new AssertFailedException(Message.AddSeparator()); + throw new AssertFailedException(Message.AddSeparator()!); } } @@ -71,6 +71,6 @@ public ValueChecker Throw(string? Message = null) where { return Assert.That.Value(exception).As($"{Message.AddSeparator()}Получено исключение, отличное от ожидаемого"); } - throw new AssertFailedException(Message.AddSeparator()); + throw new AssertFailedException(Message.AddSeparator()!); } } \ No newline at end of file diff --git a/MathCore.TestsExtensions/Checkers/CollectionChecker.cs b/MathCore.TestsExtensions/Checkers/CollectionChecker.cs index 075472f..3c61deb 100644 --- a/MathCore.TestsExtensions/Checkers/CollectionChecker.cs +++ b/MathCore.TestsExtensions/Checkers/CollectionChecker.cs @@ -48,7 +48,11 @@ public CollectionChecker IsEqualTo(ICollection ExpectedCollection, string? if (!Equals(expected, actual)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -107,7 +111,11 @@ public CollectionChecker IsEqualTo(ICollection ExpectedCollection, Equalit if (!Comparer(expected, actual)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -165,7 +173,11 @@ public CollectionChecker IsEqualTo(ICollection ExpectedCollection, Equalit if (!Comparer(expected, actual, index)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -216,7 +228,11 @@ public CollectionChecker IsEqualTo(ICollection ExpectedCollection, IEquali if (!Comparer.Equals(expected, actual)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -264,7 +280,11 @@ public CollectionChecker IsEqualTo(params T[] items) var expected = items[index]; if (!Equals(actual, expected)) - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //Assert.That.Value(actual).IsEqual(items[index], $"item[{index}]"); index++; } @@ -302,7 +322,11 @@ public CollectionChecker IsEqualTo(string Message, params T[] items) var expected = items[index]; if (!Equals(actual, expected)) - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //Assert.That.Value(actual).IsEqual(items[index], $"item[{index}]{Message}"); index++; } @@ -341,7 +365,11 @@ public CollectionChecker IsEqualTo(IEnumerable ExpectedItems, string? Mess if (!Equals(expected, actual)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -461,7 +489,7 @@ public CollectionChecker Contains(T item, string? Message = null) /// Сообщение, выводимое в случае если условие не выполнено public CollectionChecker Contains(Func Predicate, string? Message = null) { - Assert.IsTrue(ActualValue.Any(Predicate), "{0}Коллекция не содержит элемент, удовлетворяющий заданным параметрам", Message.AddSeparator()); + Assert.IsTrue(ActualValue.Any(Predicate), $"{Message.AddSeparator()}Коллекция не содержит элемент, удовлетворяющий заданным параметрам"); return this; } @@ -470,7 +498,7 @@ public CollectionChecker Contains(Func Predicate, string? Message = /// Сообщение, выводимое в случае неудачи public CollectionChecker NotContains(T item, string? Message = null) { - Assert.IsTrue(!ActualValue.Contains(item), "{0}Коллекция содержит элемент {1}", Message.AddSeparator(), item); + Assert.DoesNotContain(item, ActualValue, $"{Message.AddSeparator()}Коллекция содержит элемент {item}"); return this; } @@ -479,7 +507,7 @@ public CollectionChecker NotContains(T item, string? Message = null) /// Сообщение, выводимое в случае если условие не выполнено public CollectionChecker NotContains(Func Predicate, string? Message = null) { - Assert.IsFalse(ActualValue.Any(Predicate), "{0}Коллекция не содержит элемент, удовлетворяющий заданным параметрам", Message.AddSeparator()); + Assert.IsFalse(ActualValue.Any(Predicate), $"{Message.AddSeparator()}Коллекция не содержит элемент, удовлетворяющий заданным параметрам"); return this; } @@ -554,6 +582,7 @@ public CollectionChecker IsSingleItem(string? Message = null) #region Implementation of IEnumerable public IEnumerator GetEnumerator() => ActualValue.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)ActualValue).GetEnumerator(); #endregion diff --git a/MathCore.TestsExtensions/Checkers/DoubleCollectionChecker.cs b/MathCore.TestsExtensions/Checkers/DoubleCollectionChecker.cs index 62e8a26..14ae11b 100644 --- a/MathCore.TestsExtensions/Checkers/DoubleCollectionChecker.cs +++ b/MathCore.TestsExtensions/Checkers/DoubleCollectionChecker.cs @@ -71,9 +71,15 @@ public EqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? Message if (delta_abs < Accuracy) { - assert_fails.Add($"[{index,3}]\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}] + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + eps:{Accuracy} + """); //FormattableString message = $"{Message}error[{index}]\r\n ожидалось:{expected}\r\n получено:{actual}\r\n accuracy:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + //throw new AssertFailedException(message.ToStringInvariant()); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); @@ -99,9 +105,15 @@ public EqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? Message if (delta_abs > Accuracy) { - assert_fails.Add($"[{index,3}]\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}] + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + eps:{Accuracy} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n accuracy:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + //throw new AssertFailedException(message.ToStringInvariant()); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); @@ -126,7 +138,7 @@ public EqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? Message var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture)), + (S, s) => S.AppendLine(s.ToStringInvariant()), S => S.ToString()); throw new AssertFailedException(message) .AddData("Expected", _ExpectedValues) @@ -225,9 +237,14 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, if (!expected.Equals(actual)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta:e3}(rel.err:{delta / expected})"; - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + //throw new AssertFailedException(message.ToStringInvariant()); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); @@ -239,7 +256,7 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, // "{0}error[{1}]: ожидалось({2}), получено({3}), err:{4}(rel:{5})", // Message, index, expected, actual, // delta.ToString("e3", CultureInfo.InvariantCulture), - // (delta / expected).ToString(CultureInfo.InvariantCulture)); + // (delta / expected).ToStringInvariant()); index++; } @@ -255,7 +272,7 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture)), + (S, s) => S.AppendLine(s.ToStringInvariant()), S => S.ToString()); throw new AssertFailedException(message) .AddData("Expected", ExpectedCollection) @@ -312,9 +329,15 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, if (delta_abs > Accuracy) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + eps:{Accuracy} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n eps:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + //throw new AssertFailedException(message.ToStringInvariant()); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); @@ -325,7 +348,7 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, // "{0}error[{1}]: ожидалось({2}), получено({3}), eps:{4}, err:{5}(rel:{6})", // Message, index, expected, actual, Accuracy, // delta.ToString("e3", CultureInfo.InvariantCulture), - // (delta / expected).ToString(CultureInfo.InvariantCulture)); + // (delta / expected).ToStringInvariant()); index++; } @@ -341,7 +364,7 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture))); + (S, s) => S.AppendLine(s.ToStringInvariant())); throw new AssertFailedException(message.ToString()) .AddData("Expected", ExpectedCollection) .AddData("Actual", _ActualCollection) @@ -397,9 +420,14 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, if (!Comparer.Equals(actual, expected)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n eps:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + //throw new AssertFailedException(message.ToStringInvariant()); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); @@ -410,7 +438,7 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, // "{0}error[{1}]: ожидалось({2}), получено({3}), eps:{4}, err:{5}(rel:{6})", // Message, index, expected, actual, Accuracy, // delta.ToString("e3", CultureInfo.InvariantCulture), - // (delta / expected).ToString(CultureInfo.InvariantCulture)); + // (delta / expected).ToStringInvariant()); index++; } @@ -426,7 +454,7 @@ public DoubleCollectionChecker IsEqualTo(ICollection ExpectedCollection, var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture))); + (S, s) => S.AppendLine(s.ToStringInvariant())); throw new AssertFailedException(message.ToString()) .AddData("Expected", ExpectedCollection) .AddData("Actual", _ActualCollection) @@ -455,11 +483,16 @@ public DoubleCollectionChecker ElementsAreEqualTo(double ExpectedValue, string? { var delta = ExpectedValue - actual_value; var delta_abs = Math.Abs(delta); - assert_fails.Add($"[{index,3}]:\r\n {actual_value}\r\n != {ExpectedValue}\r\n err:{delta_abs:e2}(err.rel:{delta_abs / ExpectedValue:e2})"); + assert_fails.Add($""" + [{index,3}]: + {actual_value} + != {ExpectedValue} + err:{delta_abs:e2}(err.rel:{delta_abs / ExpectedValue:e2}) + """); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + //throw new AssertFailedException(message.ToStringInvariant()); } //Assert.AreEqual(ExpectedValue, actual_value, @@ -479,7 +512,7 @@ public DoubleCollectionChecker ElementsAreEqualTo(double ExpectedValue, string? var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture)), + (S, s) => S.AppendLine(s.ToStringInvariant()), S => S.ToString()); throw new AssertFailedException(message) .AddData("Expected", ExpectedValue) @@ -510,8 +543,14 @@ public DoubleCollectionChecker ElementsAreEqualTo(double ExpectedValue, double A if (delta_abs > Accuracy) { var rel_delta = delta / ExpectedValue; - assert_fails.Add($"[{index,3}]:\r\n {actual_value}\r\n != {ExpectedValue}\r\n err:{delta_abs:e2}(rel.err:{rel_delta:e3})\r\n eps:{Accuracy}"); - //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + assert_fails.Add($""" + [{index,3}]: + {actual_value} + != {ExpectedValue} + err:{delta_abs:e2}(rel.err:{rel_delta:e3}) + eps:{Accuracy} + """); + //throw new AssertFailedException(message.ToStringInvariant()); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); @@ -539,7 +578,7 @@ public DoubleCollectionChecker ElementsAreEqualTo(double ExpectedValue, double A var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture)), + (S, s) => S.AppendLine(s.ToStringInvariant()), S => S.ToString()); throw new AssertFailedException(message) .AddData("Expected", ExpectedValue) @@ -563,7 +602,7 @@ public DoubleCollectionChecker ElementsAreSatisfyCondition(ElementChecker Condit { if (!Condition(actual_value)) assert_fails.Add($"[{index,3}]:{actual_value} не удовлетворяет заданному условию"); - //Assert.IsTrue(Condition(actual_value), "{0}err.value[{1}]:{2}", Message, index, actual_value.ToString(CultureInfo.InvariantCulture)); + //Assert.IsTrue(Condition(actual_value), "{0}err.value[{1}]:{2}", Message, index, actual_value.ToStringInvariant()); index++; } @@ -571,7 +610,7 @@ public DoubleCollectionChecker ElementsAreSatisfyCondition(ElementChecker Condit var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture)), + (S, s) => S.AppendLine(s.ToStringInvariant()), S => S.ToString()); throw new AssertFailedException(message) .AddData("Condition", Condition) @@ -595,7 +634,7 @@ public DoubleCollectionChecker ElementsAreSatisfyCondition(PositionElementChecke { if (!Condition(actual_value, index)) assert_fails.Add($"[{index,3}]:{actual_value} не удовлетворяет заданному условию"); - //Assert.IsTrue(Condition(actual_value, index), "{0}err.value[{1}]:{2}", Message, index, actual_value.ToString(CultureInfo.InvariantCulture)); + //Assert.IsTrue(Condition(actual_value, index), "{0}err.value[{1}]:{2}", Message, index, actual_value.ToStringInvariant()); index++; } @@ -603,7 +642,7 @@ public DoubleCollectionChecker ElementsAreSatisfyCondition(PositionElementChecke var message = assert_fails.Aggregate( new StringBuilder(Message.AddSeparator(Environment.NewLine)), - (S, s) => S.AppendLine(s.ToString(CultureInfo.InvariantCulture)), + (S, s) => S.AppendLine(s.ToStringInvariant()), S => S.ToString()); throw new AssertFailedException(message) .AddData(Condition) diff --git a/MathCore.TestsExtensions/Checkers/DoubleCompareCheckerWithAccuracy.cs b/MathCore.TestsExtensions/Checkers/DoubleCompareCheckerWithAccuracy.cs index d7ce801..fca8036 100644 --- a/MathCore.TestsExtensions/Checkers/DoubleCompareCheckerWithAccuracy.cs +++ b/MathCore.TestsExtensions/Checkers/DoubleCompareCheckerWithAccuracy.cs @@ -47,7 +47,13 @@ public DoubleCompareCheckerWithAccuracy WithAccuracy(double Accuracy, string? Me if (!(_ActualValue - Math.Abs(Accuracy) <= _ExpectedValue)) { var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Значение\r\n {_ActualValue} должно быть меньше, либо равно\r\n {_ExpectedValue}\r\n err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue)/_ExpectedValue:e2})\r\n eps:{Accuracy}"; + FormattableString message = $""" + {msg}Значение + {_ActualValue} должно быть меньше, либо равно + {_ExpectedValue} + err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue)/_ExpectedValue:e2}) + eps:{Accuracy} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", _ExpectedValue) .AddData("Actual", _ActualValue) @@ -57,7 +63,13 @@ public DoubleCompareCheckerWithAccuracy WithAccuracy(double Accuracy, string? Me if (!(_ActualValue - Math.Abs(Accuracy) < _ExpectedValue)) { var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Значение\r\n {_ActualValue} должно быть меньше\r\n {_ExpectedValue}\r\n err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue) / _ExpectedValue:e2})\r\n eps{Accuracy}."; + FormattableString message = $""" + {msg}Значение + {_ActualValue} должно быть меньше + {_ExpectedValue} + err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue) / _ExpectedValue:e2}) + eps{Accuracy}. + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", _ExpectedValue) .AddData("Actual", _ActualValue) @@ -70,7 +82,13 @@ public DoubleCompareCheckerWithAccuracy WithAccuracy(double Accuracy, string? Me if (!(_ActualValue + Math.Abs(Accuracy) >= _ExpectedValue)) { var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Значение\r\n {_ActualValue} должно быть больше, либо равно\r\n {_ExpectedValue}\r\n err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue) / _ExpectedValue:e2})\r\n eps:{Accuracy}"; + FormattableString message = $""" + {msg}Значение + {_ActualValue} должно быть больше, либо равно + {_ExpectedValue} + err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue) / _ExpectedValue:e2}) + eps:{Accuracy} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", _ExpectedValue) .AddData("Actual", _ActualValue) @@ -80,7 +98,13 @@ public DoubleCompareCheckerWithAccuracy WithAccuracy(double Accuracy, string? Me if (!(_ActualValue + Math.Abs(Accuracy) > _ExpectedValue)) { var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Значение\r\n {_ActualValue} должно быть больше\r\n {_ExpectedValue}\r\n err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue)/_ExpectedValue:e2})\r\n eps:{Accuracy}"; + FormattableString message = $""" + {msg}Значение + {_ActualValue} должно быть больше + {_ExpectedValue} + err:{_ExpectedValue - _ActualValue:e2}(err.rel:{(_ExpectedValue - _ActualValue)/_ExpectedValue:e2}) + eps:{Accuracy} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", _ExpectedValue) .AddData("Actual", _ActualValue) diff --git a/MathCore.TestsExtensions/Checkers/DoubleDimensionArrayChecker.cs b/MathCore.TestsExtensions/Checkers/DoubleDimensionArrayChecker.cs index 3595e9a..f946232 100644 --- a/MathCore.TestsExtensions/Checkers/DoubleDimensionArrayChecker.cs +++ b/MathCore.TestsExtensions/Checkers/DoubleDimensionArrayChecker.cs @@ -20,8 +20,9 @@ public class DoubleDimensionArrayChecker public DoubleDimensionArrayChecker IsEqualTo(double[,] ExpectedArray, string? Message = null) { Service.CheckSeparator(ref Message); - Assert.AreEqual(ExpectedArray.GetLength(0), ActualValue.GetLength(0), "{0}{1}", Message, "Размеры массивов не совпадают"); - Assert.AreEqual(ExpectedArray.GetLength(1), ActualValue.GetLength(1), "{0}{1}", Message, "Размеры массивов не совпадают"); + Message ??= "Размеры массивов не совпадают"; + Assert.AreEqual(ExpectedArray.GetLength(0), ActualValue.GetLength(0), Message); + Assert.AreEqual(ExpectedArray.GetLength(1), ActualValue.GetLength(1), Message); for (var i = 0; i < ActualValue.GetLength(0); i++) for (var j = 0; j < ActualValue.GetLength(1); j++) @@ -29,10 +30,11 @@ public DoubleDimensionArrayChecker IsEqualTo(double[,] ExpectedArray, string? Me var expected = ExpectedArray[i, j]; var actual = ActualValue[i, j]; Assert.AreEqual(expected, actual, - "{0}Несовпадение по индексу [{1},{2}], ожидалось:{3}; получено:{4}\r\n err:{5}(rel:{6})", - Message, i, j, expected, actual, - Math.Abs(expected - actual).ToString("e3", CultureInfo.InvariantCulture), - (Math.Abs(expected - actual) / expected).ToString(CultureInfo.InvariantCulture)); + FormattableString.Invariant( + $""" + {Message}Несовпадение по индексу [{i},{j}], ожидалось:{expected}; получено:{actual} + err:{Math.Abs(expected - actual):e3}(rel:{(Math.Abs(expected - actual) / expected)}) + """)); } return this; @@ -48,8 +50,9 @@ public DoubleDimensionArrayChecker IsEqualTo(double[,] ExpectedArray, double Acc throw new ArgumentException("Значение точности не может быть равно NaN", nameof(Accuracy)); Service.CheckSeparator(ref Message); - Assert.AreEqual(ExpectedArray.GetLength(0), ActualValue.GetLength(0), "{0}{1}", Message, "Размеры массивов не совпадают"); - Assert.AreEqual(ExpectedArray.GetLength(1), ActualValue.GetLength(1), "{0}{1}", Message, "Размеры массивов не совпадают"); + Message ??= "Размеры массивов не совпадают"; + Assert.AreEqual(ExpectedArray.GetLength(0), ActualValue.GetLength(0), Message); + Assert.AreEqual(ExpectedArray.GetLength(1), ActualValue.GetLength(1), Message); for (var i = 0; i < ActualValue.GetLength(0); i++) for (var j = 0; j < ActualValue.GetLength(1); j++) @@ -66,15 +69,20 @@ public DoubleDimensionArrayChecker IsEqualTo(double[,] ExpectedArray, double Acc var delta = Math.Abs(expected - actual); if (delta > Accuracy) { - FormattableString message = $"{Message}Несовпадение по индексу [{i},{j}]\r\n ожидалось:{expected}; получено:{actual}\r\n err:{delta:e3}(rel:{delta / expected:e3})\r\n eps:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + FormattableString message = $""" + {Message}Несовпадение по индексу [{i},{j}] + ожидалось:{expected}; получено:{actual} + err:{delta:e3}(rel:{delta / expected:e3}) + eps:{Accuracy} + """; + throw new AssertFailedException(message.ToStringInvariant()); } //Assert.AreEqual(expected, actual, Accuracy, // "{0}Несовпадение по индексу [{1},{2}], ожидалось:{3}; получено:{4}; delta:{5}; err:{6}(rel:{7})", // Message, i, j, expected, actual, Accuracy, // Math.Abs(expected - actual).ToString("e3", CultureInfo.InvariantCulture), - // (Math.Abs(expected - actual) / expected).ToString(CultureInfo.InvariantCulture)); + // (Math.Abs(expected - actual) / expected).ToStringInvariant()); } return this; @@ -94,15 +102,19 @@ public DoubleDimensionArrayChecker ElementsAreEqualTo(double ExpectedValue, stri if (ExpectedValue != actual) { var delta = Math.Abs(ExpectedValue - actual); - FormattableString message = $"{Message}Несовпадение по индексу [{i},{j}]\r\n ожидалось:{ExpectedValue}; получено:{actual}\r\n err:{delta:e3}(rel:{delta / ExpectedValue:e3})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + FormattableString message = $""" + {Message}Несовпадение по индексу [{i},{j}] + ожидалось:{ExpectedValue}; получено:{actual} + err:{delta:e3}(rel:{delta / ExpectedValue:e3}) + """; + throw new AssertFailedException(message.ToStringInvariant()); } //Assert.AreEqual(ExpectedValue, actual, // "{0}Несовпадение по индексу [{1},{2}], ожидалось:{3}; получено:{4}; err:{5}(rel:{6})", // Message, i, j, ExpectedValue, actual, // Math.Abs(ExpectedValue - actual).ToString("e3", CultureInfo.InvariantCulture), - // (Math.Abs(ExpectedValue - actual) / ExpectedValue).ToString(CultureInfo.InvariantCulture)); + // (Math.Abs(ExpectedValue - actual) / ExpectedValue).ToStringInvariant()); } return this; @@ -123,15 +135,20 @@ public DoubleDimensionArrayChecker ElementsAreEqualTo(double ExpectedValue, doub var delta = Math.Abs(ExpectedValue - actual); if (delta > Accuracy) { - FormattableString message = $"{Message}Несовпадение по индексу [{i},{j}]\r\n ожидалось:{ExpectedValue}; получено:{actual}\r\n delta:{Accuracy}\r\n err:{delta:e3}(rel:{delta / ExpectedValue:e3})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + FormattableString message = $""" + {Message}Несовпадение по индексу [{i},{j}] + ожидалось:{ExpectedValue}; получено:{actual} + delta:{Accuracy} + err:{delta:e3}(rel:{delta / ExpectedValue:e3}) + """; + throw new AssertFailedException(message.ToStringInvariant()); } //Assert.AreEqual(ExpectedValue, actual, Accuracy, // "{0}Несовпадение по индексу [{1},{2}], ожидалось:{3}; получено:{4}; delta:{5}; err:{6}(rel:{7})", // Message, i, j, ExpectedValue, actual, Accuracy, // delta.ToString("e3", CultureInfo.InvariantCulture), - // (delta / ExpectedValue).ToString(CultureInfo.InvariantCulture)); + // (delta / ExpectedValue).ToStringInvariant()); } return this; @@ -156,7 +173,7 @@ public DoubleDimensionArrayChecker ElementsAreSatisfyCondition(ElementChecker Co if (!Condition(actual)) { FormattableString message = $"{Message}err[{i},{j}]:{actual}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + throw new AssertFailedException(message.ToStringInvariant()); } //Assert.IsTrue(Condition(actual), "{0}err[{1},{2}]:{3}", Message, i, j, actual); @@ -185,8 +202,11 @@ public DoubleDimensionArrayChecker ElementsAreSatisfyCondition(PositionElementCh if (!Condition(actual, i, j)) { - FormattableString message = $"{Message}err[{i},{j}]:\r\n {actual}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + FormattableString message = $""" + {Message}err[{i},{j}]: + {actual} + """; + throw new AssertFailedException(message.ToStringInvariant()); } //Assert.IsTrue(Condition(actual, i, j), "{0}err[{1},{2}]:{3}", Message, i, j, actual); diff --git a/MathCore.TestsExtensions/Checkers/DoubleEqualityCheckerWithAccuracy.cs b/MathCore.TestsExtensions/Checkers/DoubleEqualityCheckerWithAccuracy.cs index 8b09af7..80e4fd0 100644 --- a/MathCore.TestsExtensions/Checkers/DoubleEqualityCheckerWithAccuracy.cs +++ b/MathCore.TestsExtensions/Checkers/DoubleEqualityCheckerWithAccuracy.cs @@ -51,8 +51,13 @@ public DoubleEqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? M if (delta < Accuracy) { var msg = Message.AddSeparator(); - FormattableString message = $"{msg} actual:{_ActualValue} ==\r\nexpected:{_ExpectedValue}\r\n err:{delta:e2}(rel:{delta_rel:e2})\r\n eps:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + FormattableString message = $""" + {msg} actual:{_ActualValue} == + expected:{_ExpectedValue} + err:{delta:e2}(rel:{delta_rel:e2}) + eps:{Accuracy} + """; + throw new AssertFailedException(message.ToStringInvariant()) .AddData("Expected", _ExpectedValue) .AddData("Actual", _ActualValue) .AddData(Accuracy); @@ -72,8 +77,13 @@ public DoubleEqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? M if (delta > Accuracy) { var msg = Message.AddSeparator(); - FormattableString message = $"{msg} actual:{_ActualValue} !=\r\nexpected:{_ExpectedValue}\r\n err:{delta:e2}(rel:{delta_rel:e2})\r\n eps:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + FormattableString message = $""" + {msg} actual:{_ActualValue} != + expected:{_ExpectedValue} + err:{delta:e2}(rel:{delta_rel:e2}) + eps:{Accuracy} + """; + throw new AssertFailedException(message.ToStringInvariant()) .AddData("Expected", _ExpectedValue) .AddData("Actual", _ActualValue) .AddData(Accuracy); diff --git a/MathCore.TestsExtensions/Checkers/DoubleReadOnlyCollectionChecker.cs b/MathCore.TestsExtensions/Checkers/DoubleReadOnlyCollectionChecker.cs index 18c0231..8b4cde5 100644 --- a/MathCore.TestsExtensions/Checkers/DoubleReadOnlyCollectionChecker.cs +++ b/MathCore.TestsExtensions/Checkers/DoubleReadOnlyCollectionChecker.cs @@ -71,7 +71,13 @@ public EqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? Message if (delta_abs < Accuracy) { - assert_fails.Add($"[{index,3}]\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}] + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + eps:{Accuracy} + """); //FormattableString message = $"{Message}error[{index}]\r\n ожидалось:{expected}\r\n получено:{actual}\r\n accuracy:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); min_delta = Math.Min(min_delta, delta); @@ -99,7 +105,13 @@ public EqualityCheckerWithAccuracy WithAccuracy(double Accuracy, string? Message if (delta_abs > Accuracy) { - assert_fails.Add($"[{index,3}]\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}] + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + eps:{Accuracy} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n accuracy:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); min_delta = Math.Min(min_delta, delta); @@ -225,7 +237,12 @@ public DoubleReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection Exp if (!expected.Equals(actual)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta:e3}(rel.err:{delta / expected})"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); @@ -312,7 +329,13 @@ public DoubleReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection Exp if (delta_abs > Accuracy) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + eps:{Accuracy} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n eps:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); min_delta = Math.Min(min_delta, delta); @@ -397,7 +420,12 @@ public DoubleReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection Exp if (!Comparer.Equals(actual, expected)) { - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n err:{delta_abs:e3}(rel.err:{delta_abs / expected})"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + err:{delta_abs:e3}(rel.err:{delta_abs / expected}) + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}\r\n eps:{Accuracy}\r\n err:{delta:e3}(rel.err:{delta / expected})"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); min_delta = Math.Min(min_delta, delta); @@ -455,7 +483,12 @@ public DoubleReadOnlyCollectionChecker ElementsAreEqualTo(double ExpectedValue, { var delta = ExpectedValue - actual_value; var delta_abs = Math.Abs(delta); - assert_fails.Add($"[{index,3}]:\r\n {actual_value}\r\n != {ExpectedValue}\r\n err:{delta_abs:e2}(err.rel:{delta_abs / ExpectedValue:e2})"); + assert_fails.Add($""" + [{index,3}]: + {actual_value} + != {ExpectedValue} + err:{delta_abs:e2}(err.rel:{delta_abs / ExpectedValue:e2}) + """); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); max_error = Math.Max(max_error, delta_abs); @@ -510,7 +543,13 @@ public DoubleReadOnlyCollectionChecker ElementsAreEqualTo(double ExpectedValue, if (delta_abs > Accuracy) { var rel_delta = delta / ExpectedValue; - assert_fails.Add($"[{index,3}]:\r\n {actual_value}\r\n != {ExpectedValue}\r\n err:{delta_abs:e2}(rel.err:{rel_delta:e3})\r\n eps:{Accuracy}"); + assert_fails.Add($""" + [{index,3}]: + {actual_value} + != {ExpectedValue} + err:{delta_abs:e2}(rel.err:{rel_delta:e3}) + eps:{Accuracy} + """); //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); min_delta = Math.Min(min_delta, delta); max_delta = Math.Max(max_delta, delta); diff --git a/MathCore.TestsExtensions/Checkers/DoubleValueChecker.cs b/MathCore.TestsExtensions/Checkers/DoubleValueChecker.cs index 87e0dce..153fff6 100644 --- a/MathCore.TestsExtensions/Checkers/DoubleValueChecker.cs +++ b/MathCore.TestsExtensions/Checkers/DoubleValueChecker.cs @@ -18,7 +18,12 @@ public override ValueChecker IsEqual(double ExpectedValue, string? Messa { if (Equals(ExpectedValue, ActualValue)) return this; - FormattableString msg = $"{Message.AddSeparator()} получено значение\r\n {ActualValue:F18} не равно ожидаемому\r\n {ExpectedValue:F18}\r\n err:{ExpectedValue - ActualValue:e3}(rel.err:{(ExpectedValue - ActualValue) / ExpectedValue:e3})"; + FormattableString msg = $""" + {Message.AddSeparator()} получено значение + {ActualValue:F18} не равно ожидаемому + {ExpectedValue:F18} + err:{ExpectedValue - ActualValue:e3}(rel.err:{(ExpectedValue - ActualValue) / ExpectedValue:e3}) + """; throw new AssertFailedException(msg.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) .AddData("Actual", ActualValue); @@ -32,7 +37,12 @@ public override ValueChecker IsNotEqual(double ExpectedValue, string? Me { if (!Equals(ExpectedValue, ActualValue)) return this; - FormattableString msg = $"{Message.AddSeparator()} полученное значение\r\n {ActualValue:F18} равно ожидаемому\r\n {ExpectedValue:F18}\r\n err:{ExpectedValue - ActualValue:e3}(rel.err:{(ExpectedValue - ActualValue) / ExpectedValue:e3})"; + FormattableString msg = $""" + {Message.AddSeparator()} полученное значение + {ActualValue:F18} равно ожидаемому + {ExpectedValue:F18} + err:{ExpectedValue - ActualValue:e3}(rel.err:{(ExpectedValue - ActualValue) / ExpectedValue:e3}) + """; throw new AssertFailedException(msg.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) .AddData("Actual", ActualValue); diff --git a/MathCore.TestsExtensions/Checkers/EnumerableChecker.cs b/MathCore.TestsExtensions/Checkers/EnumerableChecker.cs index 1094e8b..05f30fb 100644 --- a/MathCore.TestsExtensions/Checkers/EnumerableChecker.cs +++ b/MathCore.TestsExtensions/Checkers/EnumerableChecker.cs @@ -13,7 +13,11 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal static class ErrorFormatterBuilder { - private static FormattableString GetErrorStr(int index, object? Expected, object? Actual) => $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}"; + private static FormattableString GetErrorStr(int index, object? Expected, object? Actual) => $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + """; private static FormattableString GetErrorSingleStr(int index, object? Expected, object? Actual) { @@ -23,7 +27,12 @@ private static FormattableString GetErrorSingleStr(int index, object? Expected, var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorDoubleStr(int index, object? Expected, object? Actual) @@ -34,7 +43,12 @@ private static FormattableString GetErrorDoubleStr(int index, object? Expected, var err = expected - actual; var err_rel = err / expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorByteStr(int index, object? Expected, object? Actual) @@ -45,7 +59,12 @@ private static FormattableString GetErrorByteStr(int index, object? Expected, ob var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorSByteStr(int index, object? Expected, object? Actual) @@ -56,7 +75,12 @@ private static FormattableString GetErrorSByteStr(int index, object? Expected, o var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorShortStr(int index, object? Expected, object? Actual) @@ -67,7 +91,12 @@ private static FormattableString GetErrorShortStr(int index, object? Expected, o var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorUShortStr(int index, object? Expected, object? Actual) @@ -78,7 +107,12 @@ private static FormattableString GetErrorUShortStr(int index, object? Expected, var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorIntStr(int index, object? Expected, object? Actual) @@ -89,7 +123,12 @@ private static FormattableString GetErrorIntStr(int index, object? Expected, obj var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorUIntStr(int index, object? Expected, object? Actual) @@ -100,7 +139,12 @@ private static FormattableString GetErrorUIntStr(int index, object? Expected, ob var err = expected - (long?)actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorLongStr(int index, object? Expected, object? Actual) @@ -111,7 +155,12 @@ private static FormattableString GetErrorLongStr(int index, object? Expected, ob var err = expected - actual; var err_rel = err / (double?)expected; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err:e2}(err.rel:{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err:e2}(err.rel:{err_rel:e2}) + """; } private static FormattableString GetErrorULongStr(int index, object? Expected, object? Actual) @@ -125,7 +174,12 @@ private static FormattableString GetErrorULongStr(int index, object? Expected, o var sign = negative ? '-' : (char?)null; - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{sign}{err:e2}(err.rel:{sign}{err_rel:e2})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{sign}{err:e2}(err.rel:{sign}{err_rel:e2}) + """; } @@ -133,11 +187,21 @@ private static ErrorFormatter MakeFormatter(MethodInfo Subtraction, MethodInfo? { var err = Subtraction.Invoke(null, [Expected, Actual]); if (Division is null) - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err}"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err} + """; var err_rel = Division.Invoke(null, [err, Expected]); - return $"[{index,3}]:\r\n ожидалось:{Expected}\r\n получено:{Actual}\r\n err:{err}(err.rel:{err_rel})"; + return $""" + [{index,3}]: + ожидалось:{Expected} + получено:{Actual} + err:{err}(err.rel:{err_rel}) + """; }; private static ErrorFormatter GetFormatter(Type type) @@ -246,7 +310,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, string? var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -302,7 +370,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, Equalit var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -364,7 +436,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, Equalit var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -423,7 +499,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, IEquali var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -482,7 +562,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, ICompar var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -716,7 +800,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, string? Messa assert_fails.Add(formatter(index, expected, actual)); } else - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -731,7 +819,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, string? Messa var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -787,7 +879,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, EqualityCompa assert_fails.Add(formatter(index, expected, actual)); } else - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -805,7 +901,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, EqualityCompa var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -862,7 +962,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, EqualityPosit assert_fails.Add(formatter(index, expected, actual)); } else - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -877,7 +981,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, EqualityPosit var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; @@ -926,7 +1034,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, IEqualityComp assert_fails.Add(formatter(index, expected, actual)); } else - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); } @@ -944,7 +1056,11 @@ public EnumerableChecker IsEqualTo(IEnumerable ExpectedEnumerable, IEqualityComp var count_actual = index; CountItems(expected_move_next, expected_collection_enumerator, ref count_expected); CountItems(actual_move_next, actual_collection_enumerator, ref count_actual); - assert_fails.Add($"Размеры перечислений не совпадают.\r\n размер актуальной коллекции:{count_actual}\r\n размер ожидаемой коллекции:{count_expected}"); + assert_fails.Add($""" + Размеры перечислений не совпадают. + размер актуальной коллекции:{count_actual} + размер ожидаемой коллекции:{count_expected} + """); } if (assert_fails.Count == 0) return this; diff --git a/MathCore.TestsExtensions/Checkers/ReadOnlyCollectionChecker.cs b/MathCore.TestsExtensions/Checkers/ReadOnlyCollectionChecker.cs index 3cae56c..8fdd830 100644 --- a/MathCore.TestsExtensions/Checkers/ReadOnlyCollectionChecker.cs +++ b/MathCore.TestsExtensions/Checkers/ReadOnlyCollectionChecker.cs @@ -46,7 +46,11 @@ public ReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection ExpectedRea var expected = expected_collection_enumerator.Current; var actual = actual_collection_enumerator.Current; - if (!Equals(expected, actual)) assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + if (!Equals(expected, actual)) assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); //Assert.AreEqual(expected, actual, "{0}error[{1}]:\r\n ожидалось:{2}\r\n получено:{3}", Message, index, expected, actual); @@ -101,7 +105,12 @@ public ReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection ExpectedRea var expected = expected_collection_enumerator.Current; var actual = actual_collection_enumerator.Current; - if (!Comparer(expected, actual)) assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + if (!Comparer(expected, actual)) + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); //Assert.IsTrue(Comparer(expected, actual), "{0}error[{1}]:\r\n ожидалось:{2}\r\n получено:{3}", Message, index, expected, actual); @@ -155,7 +164,12 @@ public ReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection ExpectedRea var expected = expected_collection_enumerator.Current; var actual = actual_collection_enumerator.Current; - if (!Comparer(expected, actual, index)) assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + if (!Comparer(expected, actual, index)) + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); //Assert.IsTrue(Comparer(expected, actual, index), "{0}error[{1}]:\r\n ожидалось:{2}\r\n получено:{3}", Message, index, expected, actual); @@ -202,7 +216,12 @@ public ReadOnlyCollectionChecker IsEqualTo(IReadOnlyCollection ExpectedRea var expected = expected_collection_enumerator.Current; var actual = actual_collection_enumerator.Current; - if (!Comparer.Equals(expected, actual)) assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + if (!Comparer.Equals(expected, actual)) + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); //Assert.IsTrue(Comparer.Equals(expected, actual), @@ -248,7 +267,11 @@ public ReadOnlyCollectionChecker IsEqualTo(params T[] items) var expected = items[index]; if (!Equals(actual, expected)) - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //Assert.That.Value(actual).IsEqual(items[index], $"item[{index}]"); index++; } @@ -286,7 +309,11 @@ public ReadOnlyCollectionChecker IsEqualTo(string Message, params T[] items) var expected = items[index]; if (!Equals(actual, expected)) - assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //Assert.That.Value(actual).IsEqual(items[index], $"item[{index}]{Message}"); index++; } @@ -323,7 +350,12 @@ public ReadOnlyCollectionChecker IsEqualTo(IEnumerable ExpectedItems, stri var expected = expected_collection_enumerator.Current; var actual = actual_collection_enumerator.Current; - if (!Equals(expected, actual)) assert_fails.Add($"[{index,3}]:\r\n ожидалось:{expected}\r\n получено:{actual}"); + if (!Equals(expected, actual)) + assert_fails.Add($""" + [{index,3}]: + ожидалось:{expected} + получено:{actual} + """); //FormattableString message = $"{Message}error[{index}]:\r\n ожидалось:{expected}\r\n получено:{actual}"; //throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); //Assert.AreEqual(expected, actual, "{0}error[{1}]:\r\n ожидалось:{2}\r\n получено:{3}", Message, index, expected, actual); @@ -441,7 +473,7 @@ public ReadOnlyCollectionChecker Contains(T item, string? Message = null) /// Сообщение, выводимое в случае если условие не выполнено public ReadOnlyCollectionChecker Contains(Func Predicate, string? Message = null) { - Assert.IsTrue(ActualValue.Any(Predicate), "{0}Коллекция не содержит элемент, удовлетворяющий заданным параметрам", Message.AddSeparator()); + Assert.IsTrue(ActualValue.Any(Predicate), $"{Message.AddSeparator()}Коллекция не содержит элемент, удовлетворяющий заданным параметрам"); return this; } @@ -450,7 +482,7 @@ public ReadOnlyCollectionChecker Contains(Func Predicate, string? Me /// Сообщение, выводимое в случае неудачи public ReadOnlyCollectionChecker NotContains(T item, string? Message = null) { - Assert.IsTrue(!ActualValue.Contains(item), "{0}Коллекция содержит элемент {1}", Message.AddSeparator(), item); + Assert.IsFalse(ActualValue.Contains(item), $"{Message.AddSeparator()}Коллекция содержит элемент {item}"); return this; } @@ -459,7 +491,7 @@ public ReadOnlyCollectionChecker NotContains(T item, string? Message = null) /// Сообщение, выводимое в случае если условие не выполнено public ReadOnlyCollectionChecker NotContains(Func Predicate, string? Message = null) { - Assert.IsFalse(ActualValue.Any(Predicate), "{0}Коллекция не содержит элемент, удовлетворяющий заданным параметрам", Message.AddSeparator()); + Assert.IsFalse(ActualValue.Any(Predicate), $"{Message.AddSeparator()}Коллекция не содержит элемент, удовлетворяющий заданным параметрам"); return this; } diff --git a/MathCore.TestsExtensions/Checkers/ValueChecker.cs b/MathCore.TestsExtensions/Checkers/ValueChecker.cs index 02d5166..15c9cae 100644 --- a/MathCore.TestsExtensions/Checkers/ValueChecker.cs +++ b/MathCore.TestsExtensions/Checkers/ValueChecker.cs @@ -31,7 +31,11 @@ public virtual ValueChecker IsEqual(T ExpectedValue, string? Message = null) if (Equals(ExpectedValue, ActualValue)) return this; - FormattableString message = $"{Message.AddSeparator()}Актуальное значение\r\n {ActualValue} не соответствует ожидаемому\r\n {ExpectedValue}"; + FormattableString message = $""" + {Message.AddSeparator()}Актуальное значение + {ActualValue} не соответствует ожидаемому + {ExpectedValue} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) .AddData("Actual", ActualValue); @@ -43,10 +47,14 @@ public virtual ValueChecker IsEqual(T ExpectedValue, string? Message = null) /// Сообщение, выводимое в случае неудачи public ValueChecker IsEqual(T ExpectedValue, IEqualityComparer Comparer, string? Message = null) { - if (Comparer.Equals(ActualValue, ExpectedValue)) + if (Comparer.Equals(ActualValue!, ExpectedValue)) return this; - FormattableString message = $"{Message.AddSeparator()}Актуальное значение\r\n {ActualValue} не соответствует ожидаемому\r\n {ExpectedValue}"; + FormattableString message = $""" + {Message.AddSeparator()}Актуальное значение + {ActualValue} не соответствует ожидаемому + {ExpectedValue} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) .AddData("Actual", ActualValue); @@ -64,10 +72,14 @@ public ValueChecker IsEqual(T ExpectedValue, IEqualityComparer Comparer, s /// Сообщение, выводимое в случае неудачи public ValueChecker IsEqual(T ExpectedValue, EqualityComparer Comparer, string? Message = null) { - if (Comparer(ExpectedValue, ActualValue)) + if (Comparer(ExpectedValue, ActualValue!)) return this; - FormattableString message = $"{Message.AddSeparator()}Актуальное значение\r\n {ActualValue} не соответствует ожидаемому\r\n {ExpectedValue}"; + FormattableString message = $""" + {Message.AddSeparator()}Актуальное значение + {ActualValue} не соответствует ожидаемому + {ExpectedValue} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) @@ -82,7 +94,11 @@ public ValueChecker IsReferenceEquals(T ExpectedValue, string? Message = null if (ReferenceEquals(ActualValue, ExpectedValue)) return this; - FormattableString message = $"{Message.AddSeparator()}Объект актуального значения\r\n {ActualValue} не является ожидаемым\r\n {ExpectedValue} при сравнении ссылок"; + FormattableString message = $""" + {Message.AddSeparator()}Объект актуального значения + {ActualValue} не является ожидаемым + {ExpectedValue} при сравнении ссылок + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) @@ -97,7 +113,11 @@ public virtual ValueChecker IsNotEqual(T ExpectedValue, string? Message = nul if (!Equals(ExpectedValue, ActualValue)) return this; var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Актуальное значение\r\n {ActualValue} соответствует ожидаемому\r\n {ExpectedValue}"; + FormattableString message = $""" + {msg}Актуальное значение + {ActualValue} соответствует ожидаемому + {ExpectedValue} + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) .AddData("Actual", ActualValue); @@ -111,7 +131,11 @@ public ValueChecker IsNotReferenceEquals(T ExpectedValue, string? Message = n if (!ReferenceEquals(ActualValue, ExpectedValue)) return this; var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Объект актуального значения\r\n {ActualValue} является ожидаемым\r\n {ExpectedValue} при сравнении ссылок"; + FormattableString message = $""" + {msg}Объект актуального значения + {ActualValue} является ожидаемым + {ExpectedValue} при сравнении ссылок + """; throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) .AddData("Expected", ExpectedValue) .AddData("Actual", ActualValue); @@ -120,14 +144,14 @@ public ValueChecker IsNotReferenceEquals(T ExpectedValue, string? Message = n /// Ссылка на значение должна быть пустой /// Сообщение, выводимое в случае неудачи public void IsNull(string? Message = null) => - Assert.IsNull(ActualValue, "{0}Ссылка на {1} не является пустой", Message.AddSeparator(), ActualValue); + Assert.IsNull(ActualValue, $"{Message.AddSeparator()}Ссылка на {ActualValue} не является пустой"); /// Значение, гарантированно не являющееся пустой ссылкой /// Сообщение, выводимое в случае неудачи /// Значение, гарантированно не являющееся пустой ссылкой public T IsNotNull(string? Message = null) { - Assert.IsNotNull(ActualValue, "{0}Ссылка является пустой", Message.AddSeparator()); + Assert.IsNotNull(ActualValue, $"{Message.AddSeparator()}Ссылка является пустой"); return ActualValue; } @@ -150,10 +174,7 @@ public ValueChecker Is(Type ExpectedType, string? Message = null) Assert.IsInstanceOfType( ActualValue, ExpectedType, - "{0}Значение {1} не является значением типа {2}", - Message.AddSeparator(), - ActualValue?.GetType(), - ExpectedType); + $"{Message.AddSeparator()}Значение {ActualValue?.GetType()} не является значением типа {ExpectedType}"); return this; } @@ -168,10 +189,7 @@ public ValueChecker Is(string? Message = null) Assert.IsInstanceOfType( ActualValue, expected_type, - "{0}Значение {1} не является значением типа {2}", - Message.AddSeparator(), - ActualValue?.GetType(), - expected_type); + $"{Message.AddSeparator()}Значение {ActualValue?.GetType()} не является значением типа {expected_type}"); return this; } @@ -186,7 +204,11 @@ public ValueChecker As(string? Message = null) whe if (expected_type.GetTypeInfo().IsAssignableFrom(ActualValue!.GetType().GetTypeInfo())) return new((TExpectedType)ActualValue); - throw new AssertFailedException($"{Message.AddSeparator()}Значение\r\n {ActualValue?.GetType()} не является значением типа\r\n {expected_type}") + throw new AssertFailedException($""" + {Message.AddSeparator()}Значение + {ActualValue?.GetType()} не является значением типа + {expected_type} + """) .AddData("ExpectedType", expected_type) .AddData("Actual", ActualValue); } @@ -204,10 +226,11 @@ public ValueChecker As(Func WhereAll(Func> Selector, Ac /// Проверка действия над значением /// Действие, выполняемое над значением /// Объект проверки действия - public ActionChecker Method(Action action) => new(action, ActualValue); + public ActionChecker Method(Action action) => new(action, ActualValue!); /// Проверка функции над значением /// Функция, выполняемая над значением /// Объект проверки функции - public FunctionChecker Method(Func function) => new(function, ActualValue); + public FunctionChecker Method(Func function) => new(function, ActualValue!); /// Оператор неявного приведения типа объекта проверки к объекту проверяемого значения, разворачивающий значение /// Объект проверки diff --git a/MathCore.TestsExtensions/Extensions/AssertExtensions.cs b/MathCore.TestsExtensions/Extensions/AssertExtensions.cs index b614c84..490ce06 100644 --- a/MathCore.TestsExtensions/Extensions/AssertExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/AssertExtensions.cs @@ -8,116 +8,107 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Класс методов-расширений для объекта-помощника проверки public static class AssertExtensions { - /// Проверка значения - /// ТИп проверяемого значения /// Объект-помощник проверки - /// Проверяемое значение - /// Объект проверки - public static ValueChecker Value(this Assert that, T ActualValue) => new(ActualValue); - - /// Проверка вещественного значения - /// Объект-помощник проверки - /// Проверяемое значение - /// Объект проверки вещественных значений - public static DoubleValueChecker Value(this Assert that, double ActualValue) => new(ActualValue); - - /// Проверка действия - /// Объект-помощник проверки - /// Проверяемое действие - /// Объект проверки исключения - public static ActionChecker Method(this Assert that, Action action) => new(action); - - /// Проверка действия - /// Тип параметра действия - /// Объект-помощник проверки - /// Параметр - /// Проверяемое действие - /// Объект проверки исключения - public static ActionChecker Method(this Assert that, T value, Action action) => new(action, value); - - /// Проверка функции - /// Тип результата функции - /// Объект-помощник проверки - /// Проверяемая функция - /// Объект проверки исключения - public static FunctionChecker Method(this Assert that, Func function) => new(function); - - /// Проверка функции - /// Тип результата функции - /// Тип параметра функции - /// Объект-помощник проверки - /// Значение, передаваемое в функцию - /// Проверяемая функция - /// Объект проверки исключения - public static FunctionChecker Method(this Assert that, TValue value, Func function) => new(function, value); + extension(Assert that) + { + /// Проверка значения + /// ТИп проверяемого значения + /// Проверяемое значение + /// Объект проверки + public ValueChecker Value(T ActualValue) => new(ActualValue); + + /// Проверка вещественного значения + /// Проверяемое значение + /// Объект проверки вещественных значений + public DoubleValueChecker Value(double ActualValue) => new(ActualValue); + + /// Проверка действия + /// Проверяемое действие + /// Объект проверки исключения + public ActionChecker Method(Action action) => new(action); + + /// Проверка действия + /// Тип параметра действия + /// Параметр + /// Проверяемое действие + /// Объект проверки исключения + public ActionChecker Method(T value, Action action) => new(action, value); + + /// Проверка функции + /// Тип результата функции + /// Проверяемая функция + /// Объект проверки исключения + public FunctionChecker Method(Func function) => new(function); + + /// Проверка функции + /// Тип результата функции + /// Тип параметра функции + /// Значение, передаваемое в функцию + /// Проверяемая функция + /// Объект проверки исключения + public FunctionChecker Method(TValue value, Func function) => new(function, value); + } #region Collection /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static DoubleCollectionChecker Collection(this Assert assert, ICollection ActualCollection) => new(ActualCollection); - - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static DoubleCollectionChecker Collection(this Assert assert, double[] ActualCollection) => new(ActualCollection); - - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static DoubleCollectionChecker Collection(this Assert assert, List ActualCollection) => new(ActualCollection); - - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static DoubleReadOnlyCollectionChecker Collection(this Assert assert, IReadOnlyCollection ActualCollection) => new(ActualCollection); - - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static DoubleReadOnlyCollectionChecker Collection(this Assert assert, ReadOnlyCollection ActualCollection) => new(ActualCollection); - - /// Проверка двумерного массива вещественных чисел - /// Объект-помощник проверки - /// Проверяемый двумерный массив - /// Объект проверки - public static DoubleDimensionArrayChecker Collection(this Assert assert, double[,] ActualArray) => new(ActualArray); - - /// Проверка коллекции - /// Тип элементов коллекции - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static CollectionChecker Collection(this Assert assert, ICollection ActualCollection) => new(ActualCollection); - - /// Проверка коллекции - /// Тип элементов коллекции - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static CollectionChecker Collection(this Assert assert, T[] ActualCollection) => new(ActualCollection); - - /// Проверка коллекции - /// Тип элементов коллекции - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static CollectionChecker Collection(this Assert assert, List ActualCollection) => new(ActualCollection); - - /// Проверка коллекции - /// Тип элементов коллекции - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static ReadOnlyCollectionChecker Collection(this Assert assert, IReadOnlyCollection ActualCollection) => new(ActualCollection); - - /// Проверка коллекции - /// Тип элементов коллекции - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static ReadOnlyCollectionChecker Collection(this Assert assert, ReadOnlyCollection ActualCollection) => new(ActualCollection); + extension(Assert assert) + { + /// Проверяемая коллекция + /// Объект проверки + public DoubleCollectionChecker Collection(ICollection ActualCollection) => new(ActualCollection); + + /// Проверяемая коллекция + /// Объект проверки + public DoubleCollectionChecker Collection(double[] ActualCollection) => new(ActualCollection); + + /// Проверяемая коллекция + /// Объект проверки + public DoubleCollectionChecker Collection(List ActualCollection) => new(ActualCollection); + + /// Проверяемая коллекция + /// Объект проверки + public DoubleReadOnlyCollectionChecker Collection(IReadOnlyCollection ActualCollection) => new(ActualCollection); + + /// Проверяемая коллекция + /// Объект проверки + public DoubleReadOnlyCollectionChecker Collection(ReadOnlyCollection ActualCollection) => new(ActualCollection); + + /// Проверка двумерного массива вещественных чисел + /// Проверяемый двумерный массив + /// Объект проверки + public DoubleDimensionArrayChecker Collection(double[,] ActualArray) => new(ActualArray); + + /// Проверка коллекции + /// Тип элементов коллекции + /// Проверяемая коллекция + /// Объект проверки + public CollectionChecker Collection(ICollection ActualCollection) => new(ActualCollection); + + /// Проверка коллекции + /// Тип элементов коллекции + /// Проверяемая коллекция + /// Объект проверки + public CollectionChecker Collection(T[] ActualCollection) => new(ActualCollection); + + /// Проверка коллекции + /// Тип элементов коллекции + /// Проверяемая коллекция + /// Объект проверки + public CollectionChecker Collection(List ActualCollection) => new(ActualCollection); + + /// Проверка коллекции + /// Тип элементов коллекции + /// Проверяемая коллекция + /// Объект проверки + public ReadOnlyCollectionChecker Collection(IReadOnlyCollection ActualCollection) => new(ActualCollection); + + /// Проверка коллекции + /// Тип элементов коллекции + /// Проверяемая коллекция + /// Объект проверки + public ReadOnlyCollectionChecker Collection(ReadOnlyCollection ActualCollection) => new(ActualCollection); + } #endregion diff --git a/MathCore.TestsExtensions/Extensions/CollectionAssertExtensions.cs b/MathCore.TestsExtensions/Extensions/CollectionAssertExtensions.cs index 3d419af..5c11ff6 100644 --- a/MathCore.TestsExtensions/Extensions/CollectionAssertExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/CollectionAssertExtensions.cs @@ -10,20 +10,21 @@ public static class CollectionAssertExtensions //public static CollectionAssertChecker Collection(this CollectionAssert assert, ICollection ActualCollection) => new CollectionAssertChecker(ActualCollection); /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static DoubleCollectionChecker Collection(this CollectionAssert assert, ICollection ActualCollection) => new(ActualCollection); + extension(CollectionAssert assert) + { + /// Проверяемая коллекция + /// Объект проверки + public DoubleCollectionChecker Collection(ICollection ActualCollection) => new(ActualCollection); - /// Проверка двумерного массива вещественных чисел - /// Объект-помощник проверки - /// Проверяемый двумерный массив - /// Объект проверки - public static DoubleDimensionArrayChecker Collection(this CollectionAssert assert, double[,] ActualArray) => new(ActualArray); + /// Проверка двумерного массива вещественных чисел + /// Проверяемый двумерный массив + /// Объект проверки + public DoubleDimensionArrayChecker Collection(double[,] ActualArray) => new(ActualArray); - /// Проверка коллекции - /// Тип элементов коллекции - /// Объект-помощник проверки - /// Проверяемая коллекция - /// Объект проверки - public static CollectionChecker Collection(this CollectionAssert assert, ICollection ActualCollection) => new(ActualCollection); + /// Проверка коллекции + /// Тип элементов коллекции + /// Проверяемая коллекция + /// Объект проверки + public CollectionChecker Collection(ICollection ActualCollection) => new(ActualCollection); + } } \ No newline at end of file diff --git a/MathCore.TestsExtensions/Extensions/ObjectTestingExtensions.cs b/MathCore.TestsExtensions/Extensions/ObjectTestingExtensions.cs index 04164f3..86e4581 100644 --- a/MathCore.TestsExtensions/Extensions/ObjectTestingExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/ObjectTestingExtensions.cs @@ -12,58 +12,82 @@ // ReSharper disable once CheckNamespace namespace Microsoft.VisualStudio.TestTools.UnitTesting.Extensions; +/// Набор расширений для упрощения написания проверок в тестах public static class ObjectTestingExtensions { - public static ValueChecker Assert(this T value, Expression> expression, [CallerArgumentExpression(nameof(expression))] string? Message = null) - { - var tester = expression.Compile(true); + /// Гарантирует, что ссылка не равна null и возвращает проверяемое значение + /// Тип значения + /// Проверяемое значение + /// Сообщение об ошибке, по умолчанию используется выражение аргумента + /// Непустое значение + [return: System.Diagnostics.CodeAnalysis.NotNull] + [return: NotNullIfNotNull(nameof(value))] + // ReSharper disable ConvertToExtensionBlock + public static T AssertNotNull(this T value, [CallerArgumentExpression(nameof(value))] string? Message = null) => value.AssertThatValue().AsNotNull(Message)!; - if (tester(value)) return new(value); + /// Гарантирует, что ссылка равна null + /// Тип значения + /// Проверяемое значение + /// Сообщение об ошибке, по умолчанию используется выражение аргумента + public static void AssertIsNull(this T value, [CallerArgumentExpression(nameof(value))] string? Message = null) => value.AssertThatValue().IsNull(Message); + // ReSharper restore ConvertToExtensionBlock - FormattableString message = $"{Message.AddSeparator()}Значение {value} не удовлетворяет условию {expression}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("value", value) - .AddData("Expression", expression); + extension(T value) + { + /// Проверяет, что значение удовлетворяет переданному логическому выражению + /// Логическое выражение проверки + /// Сообщение об ошибке, по умолчанию используется выражение аргумента + /// Объект проверки значения + public ValueChecker Assert(Expression> expression, [CallerArgumentExpression(nameof(expression))] string? Message = null) + { + var tester = expression.Compile(true); - } + if (tester(value)) return new(value); - public static ValueChecker AssertThrow(this T value, Expression> ThrowException, [CallerArgumentExpression(nameof(ThrowException))] string? Message = null) where TException : Exception - { - var tester = ThrowException.Compile(true); + FormattableString message = $"{Message.AddSeparator()}Значение {value} не удовлетворяет условию {expression}"; + throw new AssertFailedException(message.ToStringInvariant()) + .AddData("value", value) + .AddData("Expression", expression); - try - { - tester(value); - FormattableString message = $"{Message.AddSeparator()}Для значения {value} выражение {ThrowException} не вызвало ошибки"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("value", value) - .AddData("Expression", ThrowException); - } - catch (TException exception) - { - return new(exception); } - catch (Exception exception) + + /// Проверяет, что выполнение выражения над значением приводит к ожидаемому исключению + /// Тип ожидаемого исключения + /// Выражение, которое должно сгенерировать исключение + /// Сообщение об ошибке, по умолчанию используется выражение аргумента + /// Объект проверки исключения + public ValueChecker AssertThrow(Expression> ThrowException, [CallerArgumentExpression(nameof(ThrowException))] string? Message = null) where TException : Exception { - FormattableString message = $"{Message.AddSeparator()}Для значения {value} выражение {ThrowException} вызвало неожиданную ошибку {exception.GetType()}:{exception.Message}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("value", value) - .AddData("Expression", ThrowException) - .AddData("exception", exception); + var tester = ThrowException.Compile(true); + + try + { + tester(value); + FormattableString message = $"{Message.AddSeparator()}Для значения {value} выражение {ThrowException} не вызвало ошибки"; + throw new AssertFailedException(message.ToStringInvariant()) + .AddData("value", value) + .AddData("Expression", ThrowException); + } + catch (TException exception) + { + return new(exception); + } + catch (Exception exception) + { + FormattableString message = $"{Message.AddSeparator()}Для значения {value} выражение {ThrowException} вызвало неожиданную ошибку {exception.GetType()}:{exception.Message}"; + throw new AssertFailedException(message.ToStringInvariant()) + .AddData("value", value) + .AddData("Expression", ThrowException) + .AddData("exception", exception); + } } } - [return: System.Diagnostics.CodeAnalysis.NotNull] - [return: NotNullIfNotNull(nameof(value))] - public static T AssertNotNull(this T value, [CallerArgumentExpression(nameof(value))] string? Message = null) => value.AssertThatValue().AsNotNull(Message)!; - - public static void AssertIsNull(this T value, [CallerArgumentExpression(nameof(value))] string? Message = null) => - value.AssertThatValue().IsNull(Message); - /// Результат является истинным /// Проверяемое выражение /// Сообщение об ошибке (при отсутствии указывается проверяемое выражение) /// Объект проверки выражения типа + // ReSharper disable once ConvertToExtensionBlock public static ValueChecker AssertTrue(this bool value, [CallerArgumentExpression(nameof(value))] string? Message = null) => That .Value(value) @@ -77,8 +101,9 @@ public static ValueChecker AssertFalse(this bool value, [CallerArgumentExp That .Value(value) .IsEqual(false, Message); + // ReSharper restore ConvertToExtensionBlock - /// Проверка выражения + /// Создаёт объект проверки значения /// Тип значения /// Проверяемое значение /// Объект проверки значения @@ -98,6 +123,12 @@ public static DoubleValueChecker AssertEquals( .Value(value) .IsEqual(ActualValue, Message); + /// Проверяет, что значение эквивалентно ожидаемому + /// Тип значения + /// Проверяемое значение + /// Ожидаемое значение + /// Сообщение об ошибке (при отсутствии указывается проверяемое выражение) + /// Объект проверки значения public static ValueChecker AssertEquals( this T value, T ActualValue, @@ -107,6 +138,12 @@ public static ValueChecker AssertEquals( .Value(value) .IsEqual(ActualValue, Message); + /// Проверяет равенство вещественного значения с заданной точностью + /// Проверяемое значение + /// Ожидаемое значение + /// Допустимая погрешность + /// Сообщение об ошибке (при отсутствии указывается проверяемое выражение) + /// Объект проверки вещественного значения public static DoubleValueChecker AssertEquals( this double value, double ActualValue, @@ -117,140 +154,286 @@ public static DoubleValueChecker AssertEquals( .Value(value) .IsEqual(ActualValue, Eps, Message); + /// Создаёт объект проверки коллекции + /// Тип элементов + /// Проверяемая коллекция + /// Объект проверки коллекции public static CollectionChecker AssertThatCollection(this ICollection collection) => That .Collection(collection); + /// Проверяет размер массива на равенство ожидаемому значению + /// Тип элементов + /// Проверяемый массив + /// Ожидаемое количество элементов + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertCount(this T[] collection, int Count, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .CountEquals(Count, Message); + /// Проверяет размер списка на равенство ожидаемому значению + /// Тип элементов + /// Проверяемый список + /// Ожидаемое количество элементов + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertCount(this List collection, int Count, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .CountEquals(Count, Message); + /// Проверяет размер коллекции на равенство ожидаемому значению + /// Тип элементов + /// Проверяемая коллекция + /// Ожидаемое количество элементов + /// Сообщение об ошибке + /// Объект проверки коллекции + // ReSharper disable ConvertToExtensionBlock public static CollectionChecker AssertCount(this ICollection collection, int Count, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .CountEquals(Count, Message); + /// Проверяет, что коллекция пуста + /// Тип элементов + /// Проверяемая коллекция + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsEmpty(this ICollection collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsEmpty(Message); + // ReSharper restore ConvertToExtensionBlock + /// Проверяет, что массив пуст + /// Тип элементов + /// Проверяемый массив + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsEmpty(this T[] collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsEmpty(Message); + /// Проверяет, что список пуст + /// Тип элементов + /// Проверяемый список + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsEmpty(this List collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsEmpty(Message); + /// Проверяет, что коллекция не пуста + /// Тип элементов + /// Проверяемая коллекция + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsNotEmpty(this ICollection collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsNotEmpty(Message); + /// Проверяет, что массив не пуст + /// Тип элементов + /// Проверяемый массив + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsNotEmpty(this T[] collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsNotEmpty(Message); + /// Проверяет, что список не пуст + /// Тип элементов + /// Проверяемый список + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsNotEmpty(this List collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsNotEmpty(Message); + /// Проверяет, что коллекция содержит ровно один элемент + /// Тип элементов + /// Проверяемая коллекция + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsSingle(this ICollection collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsSingleItem(Message); + /// Проверяет, что массив содержит ровно один элемент + /// Тип элементов + /// Проверяемый массив + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsSingle(this T[] collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsSingleItem(Message); + /// Проверяет, что список содержит ровно один элемент + /// Тип элементов + /// Проверяемый список + /// Сообщение об ошибке + /// Объект проверки коллекции public static CollectionChecker AssertIsSingle(this List collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsSingleItem(Message); + /// Проверяет коллекцию на совпадение с указанным набором значений + /// Тип элементов + /// Проверяемый массив + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this T[] collection, params T[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию на совпадение с указанным набором значений + /// Тип элементов + /// Проверяемый список + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this List collection, params T[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию на совпадение с указанным набором значений + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this ReadOnlyCollection collection, params T[] args) => That .Collection((ICollection)collection) .IsEqualTo(args); + /// Проверяет коллекцию на совпадение с указанным набором значений + /// Тип элементов + /// Проверяемый список + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this IList collection, params T[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию на совпадение с указанным набором значений + /// Тип элементов + /// Проверяемая коллекция + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this ICollection collection, params T[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию вещественных чисел на совпадение с набором значений + /// Проверяемая коллекция + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleCollectionChecker AssertEquals(this ICollection collection, params double[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию вещественных чисел на совпадение с набором значений + /// Проверяемая коллекция только для чтения + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleCollectionChecker AssertEquals(this ReadOnlyCollection collection, params double[] args) => That .Collection((ICollection)collection) .IsEqualTo(args); + /// Проверяет коллекцию на совпадение с набором значений с использованием компаратора + /// Тип элементов + /// Проверяемый массив + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this T[] collection, IEqualityComparer Comparer, params T[] args) => That .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию на совпадение с набором значений с использованием компаратора + /// Тип элементов + /// Проверяемый список + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this List collection, IEqualityComparer Comparer, params T[] args) => That .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию на совпадение с набором значений с использованием компаратора + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this ReadOnlyCollection collection, IEqualityComparer Comparer, params T[] args) => That .Collection((ICollection)collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию на совпадение с набором значений с использованием компаратора + /// Тип элементов + /// Проверяемая коллекция + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции public static CollectionChecker AssertEquals(this ICollection collection, IEqualityComparer Comparer, params T[] args) => That .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию вещественных чисел на совпадение с набором значений с использованием компаратора + /// Проверяемый массив + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleCollectionChecker AssertEquals(this double[] collection, IEqualityComparer Comparer, params double[] args) => That .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию вещественных чисел на совпадение с набором значений с использованием компаратора + /// Проверяемый список + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleCollectionChecker AssertEquals(this List collection, IEqualityComparer Comparer, params double[] args) => That .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию вещественных чисел на совпадение с набором значений с использованием компаратора + /// Проверяемая коллекция + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleCollectionChecker AssertEquals(this ICollection collection, IEqualityComparer Comparer, params double[] args) => That .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию вещественных чисел на совпадение с набором значений с использованием компаратора + /// Проверяемая коллекция только для чтения + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleCollectionChecker AssertEquals(this ReadOnlyCollection collection, IEqualityComparer Comparer, params double[] args) => That .Collection((ICollection)collection) @@ -258,40 +441,80 @@ public static DoubleCollectionChecker AssertEquals(this ReadOnlyCollectionСоздаёт объект проверки коллекции только для чтения + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertThatCollection(this IReadOnlyCollection collection) => That .Collection(collection); + /// Проверяет размер коллекции только для чтения на равенство ожидаемому значению + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Ожидаемое количество элементов + /// Сообщение об ошибке + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertCount(this IReadOnlyCollection collection, int Count, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .CountEquals(Count, Message); + /// Проверяет, что коллекция только для чтения пуста + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Сообщение об ошибке + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertIsEmpty(this IReadOnlyCollection collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsEmpty(Message); + /// Проверяет, что коллекция только для чтения не пуста + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Сообщение об ошибке + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertIsNotEmpty(this IReadOnlyCollection collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsNotEmpty(Message); + /// Проверяет, что коллекция только для чтения содержит один элемент + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Сообщение об ошибке + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertIsSingle(this IReadOnlyCollection collection, [CallerArgumentExpression(nameof(collection))] string? Message = null) => That .Collection(collection) .IsSingleItem(Message); + /// Проверяет коллекцию только для чтения на совпадение с набором значений + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Ожидаемые элементы + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertEquals(this IReadOnlyCollection collection, params T[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию вещественных чисел только для чтения на совпадение с набором значений + /// Проверяемая коллекция только для чтения + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleReadOnlyCollectionChecker AssertEquals(this IReadOnlyCollection collection, params double[] args) => That .Collection(collection) .IsEqualTo(args); + /// Проверяет коллекцию только для чтения на совпадение с набором значений с использованием компаратора + /// Тип элементов + /// Проверяемая коллекция только для чтения + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции public static ReadOnlyCollectionChecker AssertEquals( this IReadOnlyCollection collection, IEqualityComparer Comparer, @@ -300,6 +523,11 @@ public static ReadOnlyCollectionChecker AssertEquals( .Collection(collection) .IsEqualTo(args, Comparer); + /// Проверяет коллекцию вещественных чисел только для чтения на совпадение с набором значений с использованием компаратора + /// Проверяемая коллекция только для чтения + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки коллекции вещественных значений public static DoubleReadOnlyCollectionChecker AssertEquals( this IReadOnlyCollection collection, IEqualityComparer Comparer, @@ -310,35 +538,71 @@ public static DoubleReadOnlyCollectionChecker AssertEquals( /* ------------------------------------------------------------------------------------------------------------- */ + /// Создаёт объект проверки перечисления + /// Тип элементов + /// Проверяемое перечисление + /// Объект проверки перечисления public static EnumerableChecker AssertThatEnumerable(this IEnumerable items) => That .Enumerable(items); + /// Проверяет, что перечисление пусто + /// Тип элементов + /// Проверяемое перечисление + /// Сообщение об ошибке + /// Объект проверки перечисления public static EnumerableChecker AssertEnumerableIsEmpty(this IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Message = null) => That .Enumerable(items) .IsEmpty(Message); + /// Проверяет, что перечисление не пусто + /// Тип элементов + /// Проверяемое перечисление + /// Сообщение об ошибке + /// Объект проверки перечисления public static EnumerableChecker AssertEnumerableIsNotEmpty(this IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Message = null) => That .Enumerable(items) .IsNotEmpty(Message); + /// Проверяет, что перечисление содержит один элемент + /// Тип элементов + /// Проверяемое перечисление + /// Сообщение об ошибке + /// Объект проверки перечисления public static EnumerableChecker AssertEnumerableIsSingleItem(this IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Message = null) => That .Enumerable(items) .IsSingleItem(Message); + /// Проверяет, что количество элементов перечисления равно ожидаемому + /// Тип элементов + /// Проверяемое перечисление + /// Ожидаемое количество элементов + /// Сообщение об ошибке + /// Объект проверки перечисления public static EnumerableChecker AssertEnumerableCount(this IEnumerable items, int ExpectedCount, [CallerArgumentExpression(nameof(items))] string? Message = null) => That .Enumerable(items) .IsItemsCount(ExpectedCount, Message); + /// Проверяет перечисление на совпадение с указанными значениями + /// Тип элементов + /// Проверяемое перечисление + /// Ожидаемые элементы + /// Объект проверки перечисления public static EnumerableChecker AssertEquals(this IEnumerable items, params T[] values) => That .Enumerable(items) .IsEqualTo(values); + /// Проверяет перечисление на совпадение с указанными значениями с использованием компаратора + /// Тип элементов + /// Проверяемое перечисление + /// Компаратор сравнения элементов + /// Ожидаемые элементы + /// Объект проверки перечисления public static EnumerableChecker AssertEquals( this IEnumerable items, IEqualityComparer Comparer, @@ -347,6 +611,11 @@ public static EnumerableChecker AssertEquals( .Enumerable(items) .IsEqualTo(values, Comparer); + /// Проверяет, что значение меньше ожидаемого + /// Проверяемое значение + /// Ожидаемое значение + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertLessThan( this double value, double ExpectedValue, @@ -356,6 +625,12 @@ public static DoubleValueChecker AssertLessThan( .Value(value) .LessThan(ExpectedValue, Message); + /// Проверяет, что значение меньше ожидаемого с учётом допустимой погрешности + /// Проверяемое значение + /// Ожидаемое значение + /// Допустимая погрешность + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertLessThan( this double value, double ExpectedValue, @@ -366,6 +641,11 @@ public static DoubleValueChecker AssertLessThan( .Value(value) .LessThan(ExpectedValue, Accuracy, Message); + /// Проверяет, что значение меньше или равно ожидаемому + /// Проверяемое значение + /// Ожидаемое значение + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertLessOrEqualsThan( this double value, double ExpectedValue, @@ -375,6 +655,12 @@ public static DoubleValueChecker AssertLessOrEqualsThan( .Value(value) .LessOrEqualsThan(ExpectedValue, Message); + /// Проверяет, что значение меньше или равно ожидаемому с учётом допустимой погрешности + /// Проверяемое значение + /// Ожидаемое значение + /// Допустимая погрешность + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertLessOrEqualsThan( this double value, double ExpectedValue, @@ -385,6 +671,11 @@ public static DoubleValueChecker AssertLessOrEqualsThan( .Value(value) .LessOrEqualsThan(ExpectedValue, Accuracy, Message); + /// Проверяет, что значение больше ожидаемого + /// Проверяемое значение + /// Ожидаемое значение + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertGreaterThan( this double value, double ExpectedValue, @@ -394,6 +685,12 @@ public static DoubleValueChecker AssertGreaterThan( .Value(value) .GreaterThan(ExpectedValue, Message); + /// Проверяет, что значение больше ожидаемого с учётом допустимой погрешности + /// Проверяемое значение + /// Ожидаемое значение + /// Допустимая погрешность + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertGreaterThan( this double value, double ExpectedValue, @@ -404,6 +701,11 @@ public static DoubleValueChecker AssertGreaterThan( .Value(value) .GreaterThan(ExpectedValue, Accuracy, Message); + /// Проверяет, что значение больше или равно ожидаемому + /// Проверяемое значение + /// Ожидаемое значение + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertGreaterOrEqualsThan( this double value, double ExpectedValue, @@ -413,6 +715,12 @@ public static DoubleValueChecker AssertGreaterOrEqualsThan( .Value(value) .GreaterOrEqualsThan(ExpectedValue, Message); + /// Проверяет, что значение больше или равно ожидаемому с учётом допустимой погрешности + /// Проверяемое значение + /// Ожидаемое значение + /// Допустимая погрешность + /// Сообщение об ошибке + /// Объект проверки вещественного значения public static DoubleValueChecker AssertGreaterOrEqualsThan( this double value, double ExpectedValue, diff --git a/MathCore.TestsExtensions/Extensions/TestResultExtensions.cs b/MathCore.TestsExtensions/Extensions/TestResultExtensions.cs index 3360535..9986b07 100644 --- a/MathCore.TestsExtensions/Extensions/TestResultExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/TestResultExtensions.cs @@ -7,74 +7,77 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting.Extensions; public static class TestResultExtensions { - public static TestResult LogWriteLine(this TestResult result, string Text) + extension(TestResult result) { - var log = new StringBuilder(result.LogOutput).AppendLine(Text); - result.LogOutput = log.ToString(); - return result; - } - - public static TestResult ToDebug(this TestResult result, T value, [CallerArgumentExpression(nameof(value))] string? Prefix = null) - { - if (Prefix is { Length: > 0 }) + public TestResult LogWriteLine(string Text) { - FormattableString msg = $"{Prefix} = {value}"; - result.LogWriteLine(msg.ToString(CultureInfo.InvariantCulture)); + var log = new StringBuilder(result.LogOutput).AppendLine(Text); + result.LogOutput = log.ToString(); + return result; } - else + + public TestResult ToDebug(T value, [CallerArgumentExpression(nameof(value))] string? Prefix = null) { - FormattableString msg = $"{value}"; - result.LogWriteLine(msg.ToString(CultureInfo.InvariantCulture)); - } + if (Prefix is { Length: > 0 }) + { + FormattableString msg = $"{Prefix} = {value}"; + result.LogWriteLine(msg.ToString(CultureInfo.InvariantCulture)); + } + else + { + FormattableString msg = $"{value}"; + result.LogWriteLine(msg.ToString(CultureInfo.InvariantCulture)); + } - return result; - } + return result; + } - public static TestResult ToDebugEnum(this TestResult result, IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Name = null) - { - var log = new StringBuilder(result.LogOutput); - if (Name is { Length: > 0 }) - log.AppendFormat("object[] {0} = {{\r\n", Name); - var i = 0; - var culture = CultureInfo.InvariantCulture; - foreach (var item in items) + public TestResult ToDebugEnum(IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Name = null) { - if (i > 0) - log.AppendLine(","); + var log = new StringBuilder(result.LogOutput); + if (Name is { Length: > 0 }) + log.AppendFormat("object[] {0} = {{\r\n", Name); + var i = 0; + var culture = CultureInfo.InvariantCulture; + foreach (var item in items) + { + if (i > 0) + log.AppendLine(","); - FormattableString msg = $" /*[{i,2}]*/ {item}"; - log.AppendLine(msg.ToString(culture)); + FormattableString msg = $" /*[{i,2}]*/ {item}"; + log.AppendLine(msg.ToString(culture)); - i++; - } - log.AppendLine(""); - log.AppendLine("}"); + i++; + } + log.AppendLine(""); + log.AppendLine("}"); - result.LogOutput = log.ToString(); - return result; - } + result.LogOutput = log.ToString(); + return result; + } - public static TestResult ToDebugEnum(this TestResult result, IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Name = null) - { - var log = new StringBuilder(result.LogOutput); - if (Name is { Length: > 0 }) - log.AppendFormat("{0}[] {1} = {{\r\n", typeof(T).Name, Name); - var i = 0; - var culture = CultureInfo.InvariantCulture; - foreach (var item in items) + public TestResult ToDebugEnum(IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Name = null) { - if (i > 0) - log.AppendLine(","); + var log = new StringBuilder(result.LogOutput); + if (Name is { Length: > 0 }) + log.AppendFormat("{0}[] {1} = {{\r\n", typeof(T).Name, Name); + var i = 0; + var culture = CultureInfo.InvariantCulture; + foreach (var item in items) + { + if (i > 0) + log.AppendLine(","); - FormattableString msg = $" /*[{i,2}]*/ {item}"; - log.Append(msg.ToString(culture)); + FormattableString msg = $" /*[{i,2}]*/ {item}"; + log.Append(msg.ToString(culture)); - i++; - } - log.AppendLine(""); - log.AppendLine("}"); + i++; + } + log.AppendLine(""); + log.AppendLine("}"); - result.LogOutput = log.ToString(); - return result; + result.LogOutput = log.ToString(); + return result; + } } } diff --git a/MathCore.TestsExtensions/Extensions/ValueCheckerBoolExtensions.cs b/MathCore.TestsExtensions/Extensions/ValueCheckerBoolExtensions.cs index ab3d3bf..10c1c1d 100644 --- a/MathCore.TestsExtensions/Extensions/ValueCheckerBoolExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/ValueCheckerBoolExtensions.cs @@ -7,37 +7,39 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Методы-расширения для объекта проверки логических значений public static class ValueCheckerBoolExtensions { - /// Проверка значения на истинность /// Объект проверки логического значения - /// Сообщение, выводимое в случае нарушения проверки - /// Исходный объект проверки логического значения - public static ValueChecker IsTrue(this ValueChecker Checker, string? Message = null) + extension(ValueChecker Checker) { - Assert.IsTrue(Checker.ActualValue, "{0}Значение не истинно", Message.AddSeparator()); - return Checker; - } + /// Проверка значения на истинность + /// Сообщение, выводимое в случае нарушения проверки + /// Исходный объект проверки логического значения + public ValueChecker IsTrue(string? Message = null) + { + Assert.IsTrue(Checker.ActualValue, $"{Message.AddSeparator()}Значение не истинно"); + return Checker; + } - /// Проверка значения на ложно - /// Объект проверки логического значения - /// Сообщение, выводимое в случае нарушения проверки - /// Исходный объект проверки логического значения - public static ValueChecker IsFalse(this ValueChecker Checker, string? Message = null) - { - Assert.IsFalse(Checker.ActualValue, "{0}Значение не ложно", Message.AddSeparator()); - return Checker; - } + /// Проверка значения на ложно + /// Сообщение, выводимое в случае нарушения проверки + /// Исходный объект проверки логического значения + public ValueChecker IsFalse(string? Message = null) + { + Assert.IsFalse(Checker.ActualValue, $"{Message.AddSeparator()}Значение не ложно"); + return Checker; + } - /// Проверка значения на ложно - /// Объект проверки логического значения - /// Значение для проверки - /// Сообщение, выводимое в случае нарушения проверки - /// Исходный объект проверки логического значения - public static ValueChecker Is(this ValueChecker Checker, bool Value, string? Message = null) - { - if (Value) - Assert.IsTrue(Checker.ActualValue, "{0}Значение не истинно", Message.AddSeparator()); - else - Assert.IsFalse(Checker.ActualValue, "{0}Значение не ложно", Message.AddSeparator()); - return Checker; + /// Проверка значения на ложно + /// Значение для проверки + /// Сообщение, выводимое в случае нарушения проверки + /// Исходный объект проверки логического значения + public ValueChecker Is(bool Value, string? Message = null) + { + if (Value) + Assert.IsTrue(Checker.ActualValue, $"{Message.AddSeparator()}Значение не истинно"); + else + Assert.IsFalse(Checker.ActualValue, $"{Message.AddSeparator()}Значение не ложно"); + + return Checker; + } } } \ No newline at end of file diff --git a/MathCore.TestsExtensions/Extensions/ValueCheckerDoubleExtensions.cs b/MathCore.TestsExtensions/Extensions/ValueCheckerDoubleExtensions.cs index a10d252..4d9bb64 100644 --- a/MathCore.TestsExtensions/Extensions/ValueCheckerDoubleExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/ValueCheckerDoubleExtensions.cs @@ -6,408 +6,428 @@ // ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Global +using static System.Math; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Методы-расширения для объекта проверки вещественных значений public static class ValueCheckerDoubleExtensions { - /// Проверка значения на равенство - /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Объект сравнения с задаваемой точностью - public static DoubleEqualityCheckerWithAccuracy IsEqualTo( - this ValueChecker Checker, - double ExpectedValue) => - new(Checker.ActualValue, ExpectedValue); - - /// Проверка значения на неравенство - /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Объект сравнения с задаваемой точностью - public static DoubleEqualityCheckerWithAccuracy IsNotEqualTo( - this ValueChecker Checker, - double ExpectedValue) => - new(Checker.ActualValue, ExpectedValue, true); - - /// Сравнение с ожидаемым значением с задаваемой точностью - /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Точность - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки вещественного значения - public static ValueChecker IsEqual( - this ValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (double.IsNaN(ExpectedValue)) throw new ArgumentException("ExpectedValue is NaN", nameof(ExpectedValue)); - var actual_value = Checker.ActualValue; - if (double.IsNaN(actual_value)) throw new ArgumentException("Checker.ActualValue is NaN", nameof(Checker.ActualValue)); - if (double.IsNaN(Accuracy)) throw new ArgumentException("Accuracy is NaN", nameof(actual_value)); - - var value_delta = ExpectedValue - actual_value; - var value_delta_abs = Math.Abs(value_delta); - if (value_delta_abs <= Accuracy) - return Checker; - - var msg = Message.AddSeparator(Environment.NewLine); - var delta_rel = value_delta / actual_value; - var error_delta = value_delta_abs - Accuracy; - - var new_accuracy = value_delta_abs; - var expected_accuracy = new_accuracy + Math.Pow(10, (int)Math.Log10(new_accuracy) - 3); - - FormattableString message = $"{msg}Ожидаемое значение\r\n {ExpectedValue} не равно реальному\r\n {actual_value}.\r\n err:{value_delta_abs:e2}(err.rel:{delta_rel})\r\n eps:{Accuracy}(eps-delta:{error_delta:e2})\r\n Требуется точность :{expected_accuracy:e2}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка на неравенство - /// Объект проверки вещественного значения - /// Не ожидаемое значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки вещественного значения - public static ValueChecker IsNotEqual( - this ValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - Assert.AreNotEqual( - ExpectedValue, Checker.ActualValue, Accuracy, - "{0}err:{1}(rel:{2}) eps:{3}", - Message.AddSeparator(), - Math.Abs(ExpectedValue - Checker.ActualValue).ToString("e2", CultureInfo.InvariantCulture), - ((ExpectedValue - Checker.ActualValue) / Checker.ActualValue).ToString(CultureInfo.InvariantCulture), - Accuracy); - return Checker; - } - - /// Проверка, что значение больше заданного - /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static ValueChecker GreaterThan( - this ValueChecker Checker, - double ExpectedValue, - string? Message = null) - { - if (Checker.ActualValue > ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть больше\r\n {ExpectedValue}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше заданного - /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker GreaterThan( - this DoubleValueChecker Checker, - double ExpectedValue, - string? Message = null) - { - if (Checker.ActualValue > ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть больше\r\n {ExpectedValue}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше заданного - /// Объект проверки вещественного значения - /// Опорное значение - /// Точность - /// Сообщение, выводимое в случае ошибки сравнения - public static ValueChecker GreaterThan( - this ValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (Checker.ActualValue + Math.Abs(Accuracy) > ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть больше\r\n {ExpectedValue} при точности {Accuracy}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше заданного - /// Объект проверки вещественного значения - /// Опорное значение - /// Точность - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker GreaterThan( - this DoubleValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (Checker.ActualValue + Math.Abs(Accuracy) > ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть больше\r\n {ExpectedValue} при точности {Accuracy}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше, либо равно заданному - /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static ValueChecker GreaterOrEqualsThan( - this ValueChecker Checker, - double ExpectedValue, - string? Message = null) - { - if (Checker.ActualValue >= ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n delta:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше, либо равно заданному - /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker GreaterOrEqualsThan( - this DoubleValueChecker Checker, - double ExpectedValue, - string? Message = null) - { - if (Checker.ActualValue >= ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n delta:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше, либо равно заданному с заданной точностью - /// Объект проверки вещественного значения - /// Опорное значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - public static ValueChecker GreaterOrEqualsThan( - this ValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (Checker.ActualValue >= (ExpectedValue - Accuracy)) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n точность:{Accuracy:e2}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше, либо равно заданному с заданной точностью - /// Объект проверки вещественного значения - /// Опорное значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker GreaterOrEqualsThan( - this DoubleValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (Checker.ActualValue >= (ExpectedValue - Accuracy)) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n точность:{Accuracy:e2}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение меньше заданного - /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker LessThan( - this DoubleValueChecker Checker, - double ExpectedValue, - string? Message = null) - { - if (Checker.ActualValue < ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть меньше\r\n {ExpectedValue}\r\n err:{delta:e2}(rel.err:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение больше заданного - /// Объект проверки вещественного значения - /// Опорное значение - /// Точность - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker LessThan( - this DoubleValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (Checker.ActualValue - Math.Abs(Accuracy) < ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть меньше\r\n {ExpectedValue} при точности {Accuracy}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение меньше, либо равно заданному /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static ValueChecker LessOrEqualsThan( - this ValueChecker Checker, - double ExpectedValue, - string? Message = null) + extension(ValueChecker Checker) { - if (Checker.ActualValue <= ExpectedValue) + /// Проверка значения на равенство + /// Ожидаемое значение + /// Объект сравнения с задаваемой точностью + public DoubleEqualityCheckerWithAccuracy IsEqualTo(double ExpectedValue) => new(Checker.ActualValue, ExpectedValue); + + /// Проверка значения на неравенство + /// Ожидаемое значение + /// Объект сравнения с задаваемой точностью + public DoubleEqualityCheckerWithAccuracy IsNotEqualTo(double ExpectedValue) => new(Checker.ActualValue, ExpectedValue, true); + + /// Сравнение с ожидаемым значением с задаваемой точностью + /// Ожидаемое значение + /// Точность + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки вещественного значения + public ValueChecker IsEqual(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (double.IsNaN(ExpectedValue)) throw new ArgumentException("ExpectedValue is NaN", nameof(ExpectedValue)); + var actual_value = Checker.ActualValue; + if (double.IsNaN(actual_value)) throw new ArgumentException("Checker.ActualValue is NaN", nameof(Checker.ActualValue)); + if (double.IsNaN(Accuracy)) throw new ArgumentException("Accuracy is NaN", nameof(actual_value)); + + var value_delta = ExpectedValue - actual_value; + var value_delta_abs = Abs(value_delta); + if (value_delta_abs <= Accuracy) + return Checker; + + var msg = Message.AddSeparator(Environment.NewLine); + var delta_rel = value_delta / actual_value; + var error_delta = value_delta_abs - Accuracy; + + var new_accuracy = value_delta_abs; + var expected_accuracy = new_accuracy + Pow(10, (int)Log10(new_accuracy) - 3); + + FormattableString message = $""" + {msg}Ожидаемое значение + {ExpectedValue} не равно реальному + {actual_value}. + err:{value_delta_abs:e2}(err.rel:{delta_rel}) + eps:{Accuracy}(eps-delta:{error_delta:e2}) + Требуется точность :{expected_accuracy:e2} + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка на неравенство + /// Не ожидаемое значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки вещественного значения + public ValueChecker IsNotEqual(double ExpectedValue, + double Accuracy, + string? Message = null) + { + FormattableString msg = $"{Message.AddSeparator()}err:{Abs(ExpectedValue - Checker.ActualValue):e2}(rel:{(ExpectedValue - Checker.ActualValue) / Checker.ActualValue}) eps:{Accuracy}"; + Assert.AreNotEqual( + ExpectedValue, Checker.ActualValue, Accuracy, + msg.ToStringInvariant()); return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть меньше, либо равно\r\n {ExpectedValue}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + } + + /// Проверка, что значение больше заданного + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public ValueChecker GreaterThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue > ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть больше + {ExpectedValue} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } } - /// Проверка, что значение меньше, либо равно заданному /// Объект проверки вещественного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker LessOrEqualsThan( - this DoubleValueChecker Checker, - double ExpectedValue, - string? Message = null) + extension(ValueChecker Checker) { - if (Checker.ActualValue <= ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть меньше, либо равно\r\n {ExpectedValue}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue:e2})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); - } - - /// Проверка, что значение меньше, либо равно заданному - /// Объект проверки вещественного значения - /// Опорное значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - public static ValueChecker LessOrEqualsThan( - this ValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) - { - if (Checker.ActualValue <= ExpectedValue + Accuracy) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n точность:{Accuracy:e2}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + /// Проверка, что значение больше заданного + /// Опорное значение + /// Точность + /// Сообщение, выводимое в случае ошибки сравнения + public ValueChecker GreaterThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue + Abs(Accuracy) > ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть больше + {ExpectedValue} при точности {Accuracy} + err:{delta:e2}(err.rel:{delta / ExpectedValue}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение больше, либо равно заданному + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public ValueChecker GreaterOrEqualsThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue >= ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + delta:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение больше, либо равно заданному с заданной точностью + /// Опорное значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + public ValueChecker GreaterOrEqualsThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue >= (ExpectedValue - Accuracy)) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + точность:{Accuracy:e2} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } } - /// Проверка, что значение меньше, либо равно заданному /// Объект проверки вещественного значения - /// Опорное значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - public static DoubleValueChecker LessOrEqualsThan( - this DoubleValueChecker Checker, - double ExpectedValue, - double Accuracy, - string? Message = null) + extension(DoubleValueChecker Checker) { - if (Checker.ActualValue <= ExpectedValue + Accuracy) - return Checker; - - var msg = Message.AddSeparator(); - var delta = ExpectedValue - Checker.ActualValue; - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n точность:{Accuracy:e2}\r\n err:{delta:e2}(err.rel:{delta / ExpectedValue})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)); + /// Проверка, что значение больше, либо равно заданному с заданной точностью + /// Опорное значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker GreaterOrEqualsThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue >= (ExpectedValue - Accuracy)) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + точность:{Accuracy:e2} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение меньше заданного + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker LessThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue < ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть меньше + {ExpectedValue} + err:{delta:e2}(rel.err:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение больше заданного + /// Опорное значение + /// Точность + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker LessThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue - Abs(Accuracy) < ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть меньше + {ExpectedValue} при точности {Accuracy} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение больше заданного + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker GreaterThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue > ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть больше + {ExpectedValue} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение больше заданного + /// Опорное значение + /// Точность + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker GreaterThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue + Abs(Accuracy) > ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть больше + {ExpectedValue} при точности {Accuracy} + err:{delta:e2}(err.rel:{delta / ExpectedValue}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение больше, либо равно заданному + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker GreaterOrEqualsThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue >= ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + delta:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение меньше, либо равно заданному + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker LessOrEqualsThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue <= ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть меньше, либо равно + {ExpectedValue} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение меньше, либо равно заданному + /// Опорное значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + public DoubleValueChecker LessOrEqualsThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue <= ExpectedValue + Accuracy) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + точность:{Accuracy:e2} + err:{delta:e2}(err.rel:{delta / ExpectedValue}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } } - /// Значение больше (строго), чем указанное с задаваемой точностью /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Объект сравнения с задаваемой точностью - public static DoubleCompareCheckerWithAccuracy Greater( - this ValueChecker Checker, - double ExpectedValue) => - new(Checker.ActualValue, ExpectedValue, IsEquals: false, IsLessChecking: false); - - /// Значение больше, чем указанное с задаваемой точностью - /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Объект сравнения с задаваемой точностью - public static DoubleCompareCheckerWithAccuracy GreaterOrEqual( - this ValueChecker Checker, - double ExpectedValue) => - new(Checker.ActualValue, ExpectedValue, IsEquals: true, IsLessChecking: false); - - /// Значение меньше (строго), чем указанное с задаваемой точностью - /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Объект сравнения с задаваемой точностью - public static DoubleCompareCheckerWithAccuracy Less( - this ValueChecker Checker, - double ExpectedValue) => - new(Checker.ActualValue, ExpectedValue, IsEquals: false, IsLessChecking: true); - - /// Значение меньше, чем указанное с задаваемой точностью - /// Объект проверки вещественного значения - /// Ожидаемое значение - /// Объект сравнения с задаваемой точностью - public static DoubleCompareCheckerWithAccuracy LessOrEqual( - this ValueChecker Checker, - double ExpectedValue) => - new(Checker.ActualValue, ExpectedValue, IsEquals: true, IsLessChecking: true); - - /// Проверить, что значение не является не-числом - /// Объект проверки вещественного значения - /// Сообщение, выводимое в случае если проверка провалена - public static ValueChecker IsNotNaN( - this ValueChecker Checker, - string? Message = null) + extension(ValueChecker Checker) { - if (double.IsNaN(Checker.ActualValue)) - throw new AssertFailedException($"{Message.AddSeparator()}Значение не является числом"); - return Checker; + /// Проверка, что значение меньше, либо равно заданному + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + public ValueChecker LessOrEqualsThan(double ExpectedValue, + string? Message = null) + { + if (Checker.ActualValue <= ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть меньше, либо равно + {ExpectedValue} + err:{delta:e2}(err.rel:{delta / ExpectedValue:e2}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } + + /// Проверка, что значение меньше, либо равно заданному + /// Опорное значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + public ValueChecker LessOrEqualsThan(double ExpectedValue, + double Accuracy, + string? Message = null) + { + if (Checker.ActualValue <= ExpectedValue + Accuracy) + return Checker; + + var msg = Message.AddSeparator(); + var delta = ExpectedValue - Checker.ActualValue; + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + точность:{Accuracy:e2} + err:{delta:e2}(err.rel:{delta / ExpectedValue}) + """; + throw new AssertFailedException(message.ToStringInvariant()); + } } - /// Проверить, что значение является не-числом /// Объект проверки вещественного значения - /// Сообщение, выводимое в случае если проверка провалена - public static ValueChecker IsNaN( - this ValueChecker Checker, - string? Message = null) + extension(ValueChecker Checker) { - if (double.IsNaN(Checker.ActualValue)) - return Checker; - throw new AssertFailedException($"{Message.AddSeparator()}Значение не не является числом"); + /// Значение больше (строго), чем указанное с задаваемой точностью + /// Ожидаемое значение + /// Объект сравнения с задаваемой точностью + public DoubleCompareCheckerWithAccuracy Greater(double ExpectedValue) => + new(Checker.ActualValue, ExpectedValue, IsEquals: false, IsLessChecking: false); + + /// Значение больше, чем указанное с задаваемой точностью + /// Ожидаемое значение + /// Объект сравнения с задаваемой точностью + public DoubleCompareCheckerWithAccuracy GreaterOrEqual(double ExpectedValue) => + new(Checker.ActualValue, ExpectedValue, IsEquals: true, IsLessChecking: false); + + /// Значение меньше (строго), чем указанное с задаваемой точностью + /// Ожидаемое значение + /// Объект сравнения с задаваемой точностью + public DoubleCompareCheckerWithAccuracy Less(double ExpectedValue) => + new(Checker.ActualValue, ExpectedValue, IsEquals: false, IsLessChecking: true); + + /// Значение меньше, чем указанное с задаваемой точностью + /// Ожидаемое значение + /// Объект сравнения с задаваемой точностью + public DoubleCompareCheckerWithAccuracy LessOrEqual(double ExpectedValue) => + new(Checker.ActualValue, ExpectedValue, IsEquals: true, IsLessChecking: true); + + /// Проверить, что значение не является не-числом + /// Сообщение, выводимое в случае если проверка провалена + public ValueChecker IsNotNaN(string? Message = null) => double.IsNaN(Checker.ActualValue) + ? throw new AssertFailedException($"{Message.AddSeparator()}Значение не является числом") + : Checker; + + /// Проверить, что значение является не-числом + /// Сообщение, выводимое в случае если проверка провалена + public ValueChecker IsNaN(string? Message = null) => double.IsNaN(Checker.ActualValue) + ? Checker + : throw new AssertFailedException($"{Message.AddSeparator()}Значение не не является числом"); } /// Сравнение с ожидаемым значением с задаваемой точностью diff --git a/MathCore.TestsExtensions/Extensions/ValueCheckerExtensions.cs b/MathCore.TestsExtensions/Extensions/ValueCheckerExtensions.cs index ac72d29..b37c7df 100644 --- a/MathCore.TestsExtensions/Extensions/ValueCheckerExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/ValueCheckerExtensions.cs @@ -12,7 +12,7 @@ public static class ValueCheckerExtensions /// Тип проверяемого значения, которое является коллекцией объектов типа /// Тип элементов проверяемой коллекции /// Объект проверки коллекции - public static CollectionChecker Are(this ValueChecker Checker) where T : ICollection => new(Checker.ActualValue); + public static CollectionChecker Are(this ValueChecker Checker) where T : ICollection => new(Checker.ActualValue!); /// Выполнение проверки элементов коллекции /// Объект проверки одиночного значения @@ -20,8 +20,9 @@ public static class ValueCheckerExtensions /// Исходный объект проверки коллекции public static ValueChecker Items(this ValueChecker Checker, Action, int> Check) where T : IReadOnlyList { - var collection = Checker.ActualValue; + var collection = Checker.ActualValue!; var count = collection.Count; + for (var i = 0; i < count; i++) Check(new(collection[i]), i); @@ -34,7 +35,7 @@ public static ValueChecker Items(this ValueChecker Checker, Acti /// Исходный объект проверки коллекции public static ValueChecker Items(this ValueChecker Checker, Action> Check) where T : IReadOnlyList { - foreach (var checker in Checker.ActualValue.Select(c => new ValueChecker(c))) + foreach (var checker in Checker.ActualValue!.Select(c => new ValueChecker(c))) Check(checker); return Checker; diff --git a/MathCore.TestsExtensions/Extensions/ValueCheckerIntExtensions.cs b/MathCore.TestsExtensions/Extensions/ValueCheckerIntExtensions.cs index 60c88e7..fe347d5 100644 --- a/MathCore.TestsExtensions/Extensions/ValueCheckerIntExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/ValueCheckerIntExtensions.cs @@ -7,176 +7,212 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Методы-расширения для объекта проверки целочисленных значений public static class ValueCheckerIntExtensions { - /// Проверка, что проверяемое значение равно ожидаемому с заданной точностью /// Объект проверки целочисленного значения - /// Ожидаемое значение - /// Точность сравнения - /// Сообщение, выводимое в случае неудачи - /// Объект проверки целочисленного значения - public static ValueChecker IsEqual(this ValueChecker Checker, int ExpectedValue, int Accuracy, string? Message = null) + extension(ValueChecker Checker) { - var delta = Math.Abs(ExpectedValue - Checker.ActualValue); - if (delta <= Accuracy) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}actual:{Checker.ActualValue}\r\n != {ExpectedValue}\r\n err:{delta}(err.rel:{(ExpectedValue - Checker.ActualValue) / (double)Checker.ActualValue:e3})\r\n accuracy:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue) - .AddData(Accuracy); - } - - /// Проверка, что проверяемое значение не равно ожидаемому с заданной точностью - /// Объект проверки целочисленного значения - /// Ожидаемое значение - /// Точность сравнения - /// Сообщение, выводимое в случае неудачи - /// Объект проверки целочисленного значения - public static ValueChecker IsNotEqual(this ValueChecker Checker, int ExpectedValue, int Accuracy, string? Message = null) - { - var delta = Math.Abs(ExpectedValue - Checker.ActualValue); - if (delta >= Accuracy) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}actual:{Checker.ActualValue}\r\n == {ExpectedValue}\r\n err:{delta}(err.rel:{(ExpectedValue - Checker.ActualValue) / (double)Checker.ActualValue:e3})\r\n accuracy:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue) - .AddData(Accuracy); - } - - /// Проверка, что значение больше заданного - /// Объект проверки целочисленного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки целочисленного значения - public static ValueChecker GreaterThan(this ValueChecker Checker, int ExpectedValue, string? Message = null) - { - if (Checker.ActualValue > ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть больше\r\n {ExpectedValue}\r\n err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue); - } - - /// Проверка, что значение больше, либо равно заданному - /// Объект проверки целочисленного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки целочисленного значения - public static ValueChecker GreaterOrEqualsThan(this ValueChecker Checker, int ExpectedValue, string? Message = null) - { - if (Checker.ActualValue >= ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue); - } - - /// Проверка, что значение больше, либо равно заданному с заданной точностью - /// Объект проверки целочисленного значения - /// Опорное значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки целочисленного значения - public static ValueChecker GreaterOrEqualsThan(this ValueChecker Checker, int ExpectedValue, int Accuracy, string? Message = null) - { - if (Checker.ActualValue - ExpectedValue <= Accuracy) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3})\r\n accuracy:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue) - .AddData(Accuracy); - } - - /// Проверка, что значение меньше заданного - /// Объект проверки целочисленного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки целочисленного значения - public static ValueChecker LessThan(this ValueChecker Checker, int ExpectedValue, string? Message = null) - { - if (Checker.ActualValue < ExpectedValue) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Значение\r\n {Checker.ActualValue} должно быть меньше\r\n {ExpectedValue}\r\n err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue); - } - - /// Проверка, что значение меньше, либо равно заданному - /// Объект проверки целочисленного значения - /// Опорное значение - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки целочисленного значения - public static ValueChecker LessOrEqualsThan(this ValueChecker Checker, int ExpectedValue, string? Message = null) - { - if (Checker.ActualValue <= ExpectedValue) - return Checker; - - FormattableString message = $"{Message.AddSeparator()}Значение\r\n {Checker.ActualValue} должно быть меньше, либо равно\r\n {ExpectedValue}\r\n err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3})"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue); - } - - /// Проверка, что значение меньше, либо равно заданному - /// Объект проверки целочисленного значения - /// Опорное значение - /// Точность сравнения - /// Сообщение, выводимое в случае ошибки сравнения - /// Объект проверки целочисленного значения - public static ValueChecker LessOrEqualsThan(this ValueChecker Checker, int ExpectedValue, int Accuracy, string? Message = null) - { - if (ExpectedValue - Checker.ActualValue <= Accuracy) - return Checker; - - var msg = Message.AddSeparator(); - FormattableString message = $"{msg}Нарушено условие\r\n {Checker.ActualValue}\r\n >= {ExpectedValue}\r\n err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3})\r\n accuracy:{Accuracy}"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Expected", ExpectedValue) - .AddData("Actual", Checker.ActualValue) - .AddData(Accuracy); - } - - /// Проверка - является ли число чётным? - /// Объект проверки целочисленного значения - /// Сообщение, выводимое в случае ошибки - /// Объект проверки целочисленного значения - public static ValueChecker IsEven(this ValueChecker Checker, string? Message = null) - { - if (Checker.ActualValue % 2 == 0) - return Checker; - - FormattableString message = $"{Message.AddSeparator()}Число {Checker.ActualValue} не является чётным"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Actual", Checker.ActualValue); - } - - /// Проверка - является ли число нечётным? - /// Объект проверки целочисленного значения - /// Сообщение, выводимое в случае ошибки - /// Объект проверки целочисленного значения - public static ValueChecker IsOdd(this ValueChecker Checker, string? Message = null) - { - if (Checker.ActualValue % 2 != 0) - return Checker; - - FormattableString message = $"{Message.AddSeparator()}Число {Checker.ActualValue} является чётным"; - throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) - .AddData("Actual", Checker.ActualValue); + /// Проверка, что проверяемое значение равно ожидаемому с заданной точностью + /// Ожидаемое значение + /// Точность сравнения + /// Сообщение, выводимое в случае неудачи + /// Объект проверки целочисленного значения + public ValueChecker IsEqual(int ExpectedValue, int Accuracy, string? Message = null) + { + var delta = Math.Abs(ExpectedValue - Checker.ActualValue); + if (delta <= Accuracy) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}actual:{Checker.ActualValue} + != {ExpectedValue} + err:{delta}(err.rel:{(ExpectedValue - Checker.ActualValue) / (double)Checker.ActualValue:e3}) + accuracy:{Accuracy} + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue) + .AddData(Accuracy); + } + + /// Проверка, что проверяемое значение не равно ожидаемому с заданной точностью + /// Ожидаемое значение + /// Точность сравнения + /// Сообщение, выводимое в случае неудачи + /// Объект проверки целочисленного значения + public ValueChecker IsNotEqual(int ExpectedValue, int Accuracy, string? Message = null) + { + var delta = Math.Abs(ExpectedValue - Checker.ActualValue); + if (delta >= Accuracy) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}actual:{Checker.ActualValue} + == {ExpectedValue} + err:{delta}(err.rel:{(ExpectedValue - Checker.ActualValue) / (double)Checker.ActualValue:e3}) + accuracy:{Accuracy} + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue) + .AddData(Accuracy); + } + + /// Проверка, что значение больше заданного + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки целочисленного значения + public ValueChecker GreaterThan(int ExpectedValue, string? Message = null) + { + if (Checker.ActualValue > ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть больше + {ExpectedValue} + err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3}) + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue); + } + + /// Проверка, что значение больше, либо равно заданному + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки целочисленного значения + public ValueChecker GreaterOrEqualsThan(int ExpectedValue, string? Message = null) + { + if (Checker.ActualValue >= ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3}) + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue); + } + + /// Проверка, что значение больше, либо равно заданному с заданной точностью + /// Опорное значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки целочисленного значения + public ValueChecker GreaterOrEqualsThan(int ExpectedValue, int Accuracy, string? Message = null) + { + if (Checker.ActualValue - ExpectedValue <= Accuracy) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3}) + accuracy:{Accuracy} + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue) + .AddData(Accuracy); + } + + /// Проверка, что значение меньше заданного + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки целочисленного значения + public ValueChecker LessThan(int ExpectedValue, string? Message = null) + { + if (Checker.ActualValue < ExpectedValue) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}Значение + {Checker.ActualValue} должно быть меньше + {ExpectedValue} + err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3}) + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue); + } + + /// Проверка, что значение меньше, либо равно заданному + /// Опорное значение + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки целочисленного значения + public ValueChecker LessOrEqualsThan(int ExpectedValue, string? Message = null) + { + if (Checker.ActualValue <= ExpectedValue) + return Checker; + + FormattableString message = $""" + {Message.AddSeparator()}Значение + {Checker.ActualValue} должно быть меньше, либо равно + {ExpectedValue} + err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3}) + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue); + } + + /// Проверка, что значение меньше, либо равно заданному + /// Опорное значение + /// Точность сравнения + /// Сообщение, выводимое в случае ошибки сравнения + /// Объект проверки целочисленного значения + public ValueChecker LessOrEqualsThan(int ExpectedValue, int Accuracy, string? Message = null) + { + if (ExpectedValue - Checker.ActualValue <= Accuracy) + return Checker; + + var msg = Message.AddSeparator(); + FormattableString message = $""" + {msg}Нарушено условие + {Checker.ActualValue} + >= {ExpectedValue} + err:{ExpectedValue - Checker.ActualValue:e3}(err.rel:{(ExpectedValue - Checker.ActualValue) / ExpectedValue:e3}) + accuracy:{Accuracy} + """; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Expected", ExpectedValue) + .AddData("Actual", Checker.ActualValue) + .AddData(Accuracy); + } + + /// Проверка - является ли число чётным? + /// Сообщение, выводимое в случае ошибки + /// Объект проверки целочисленного значения + public ValueChecker IsEven(string? Message = null) + { + if (Checker.ActualValue % 2 == 0) + return Checker; + + FormattableString message = $"{Message.AddSeparator()}Число {Checker.ActualValue} не является чётным"; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Actual", Checker.ActualValue); + } + + /// Проверка - является ли число нечётным? + /// Сообщение, выводимое в случае ошибки + /// Объект проверки целочисленного значения + public ValueChecker IsOdd(string? Message = null) + { + if (Checker.ActualValue % 2 != 0) + return Checker; + + FormattableString message = $"{Message.AddSeparator()}Число {Checker.ActualValue} является чётным"; + throw new AssertFailedException(message.ToString(CultureInfo.InvariantCulture)) + .AddData("Actual", Checker.ActualValue); + } } } \ No newline at end of file diff --git a/MathCore.TestsExtensions/Extensions/ValueCheckerStringExtensions.cs b/MathCore.TestsExtensions/Extensions/ValueCheckerStringExtensions.cs index de3c907..69d0dec 100644 --- a/MathCore.TestsExtensions/Extensions/ValueCheckerStringExtensions.cs +++ b/MathCore.TestsExtensions/Extensions/ValueCheckerStringExtensions.cs @@ -11,152 +11,130 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Методы-расширения для объекта проверки строковых значений public static class ValueCheckerStringExtensions { - /// Проверка, что строка начинается с указанного префикса /// Объект проверки строкового значения - /// Ожидаемый префикс - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker StartWith(this ValueChecker Checker, string ExpectedPrefix, string? Message = null) + extension(ValueChecker Checker) { - StringAssert.StartsWith(Checker.ActualValue, ExpectedPrefix, - "{0}Указанная строка {1} не начинается с ожидаемого префикса {2}", - Message.AddSeparator(), - Checker.ActualValue, - ExpectedPrefix); - return Checker; - } - - /// Проверка, что строка заканчивается указанной подстрокой - /// Объект проверки строкового значения - /// Ожидаемое окончание - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker EndWith(this ValueChecker Checker, string ExpectedSuffix, string? Message = null) - { - StringAssert.EndsWith(Checker.ActualValue, ExpectedSuffix, - "{0}Указанная строка {1} не заканчивается ожидаемым окончанием {2}", - Message.AddSeparator(), - Checker.ActualValue, - ExpectedSuffix); - return Checker; - } + /// Проверка, что строка начинается с указанного префикса + /// Ожидаемый префикс + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker StartWith(string ExpectedPrefix, string? Message = null) + { + FormattableString message = $"{Message.AddSeparator()}Указанная строка {Checker.ActualValue} не начинается с ожидаемого префикса {ExpectedPrefix}"; + Assert.StartsWith(Checker.ActualValue, ExpectedPrefix, message.ToStringInvariant()); + return Checker; + } - /// Проверка, что строка содержит ожидаемую подстроку - /// Объект проверки строкового значения - /// Ожидаемая подстрока - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker Contains(this ValueChecker Checker, string ExpectedSubstring, string? Message = null) - { - StringAssert.Contains(Checker.ActualValue, ExpectedSubstring, - "{0}Указанная строка {1} не содержит ожидаемой подстроки {2}", - Message.AddSeparator(), - Checker.ActualValue, - ExpectedSubstring); - return Checker; - } + /// Проверка, что строка заканчивается указанной подстрокой + /// Ожидаемое окончание + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker EndWith(string ExpectedSuffix, string? Message = null) + { + FormattableString msg = $"{Message.AddSeparator()}Указанная строка {Checker.ActualValue} не заканчивается ожидаемым окончанием {ExpectedSuffix}"; + Assert.EndsWith(Checker.ActualValue, ExpectedSuffix, msg.ToStringInvariant()); + return Checker; + } - /// Проверка, что строка соответствует указанному регулярному выражению - /// Объект проверки строкового значения - /// Ожидаемое регулярное выражение - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker Matches(this ValueChecker Checker, [RegexPattern] string ExpectedRegEx, string? Message = null) => Checker.Matches(new Regex(ExpectedRegEx), Message); + /// Проверка, что строка содержит ожидаемую подстроку + /// Ожидаемая подстрока + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker Contains(string ExpectedSubstring, string? Message = null) + { + FormattableString msg = $"{Message.AddSeparator()}Указанная строка {Checker.ActualValue} не содержит ожидаемой подстроки {ExpectedSubstring}"; + Assert.Contains(Checker.ActualValue!, ExpectedSubstring, msg.ToStringInvariant()); + return Checker; + } - /// Проверка, что строка соответствует указанному регулярному выражению - /// Объект проверки строкового значения - /// Ожидаемое регулярное выражение - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker Matches(this ValueChecker Checker, Regex ExpectedRegEx, string? Message = null) - { - StringAssert.Matches(Checker.ActualValue, ExpectedRegEx, - "{0}Указанная строка {1} не соответствует ожидаемому регулярному выражению {2}", - Message.AddSeparator(), - Checker.ActualValue, - ExpectedRegEx); - return Checker; - } + /// Проверка, что строка соответствует указанному регулярному выражению + /// Ожидаемое регулярное выражение + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker Matches([RegexPattern] string ExpectedRegEx, string? Message = null) => Checker.Matches(new Regex(ExpectedRegEx), Message); - /// Проверка, что строка НЕ соответствует указанному регулярному выражению - /// Объект проверки строкового значения - /// Регулярное выражение, которому не должна соответствовать строка - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker DoesNotMatch(this ValueChecker Checker, [RegexPattern] string ExpectedRegEx, string? Message = null) => Checker.DoesNotMatch(new Regex(ExpectedRegEx), Message); + /// Проверка, что строка соответствует указанному регулярному выражению + /// Ожидаемое регулярное выражение + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker Matches(Regex ExpectedRegEx, string? Message = null) + { + FormattableString msg = $"{Message.AddSeparator()}Указанная строка {Checker.ActualValue} не соответствует ожидаемому регулярному выражению {ExpectedRegEx}"; + StringAssert.Matches(Checker.ActualValue, ExpectedRegEx, msg.ToStringInvariant()); + return Checker; + } - /// Проверка, что строка НЕ соответствует указанному регулярному выражению - /// Объект проверки строкового значения - /// Регулярное выражение, которому не должна соответствовать строка - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker DoesNotMatch(this ValueChecker Checker, Regex ExpectedRegEx, string? Message = null) - { - StringAssert.DoesNotMatch(Checker.ActualValue, ExpectedRegEx, - "{0}Указанная строка {1} ошибочно соответствует ожидаемому регулярному выражению {2}", - Message.AddSeparator(), - Checker.ActualValue, - ExpectedRegEx); - return Checker; - } + /// Проверка, что строка НЕ соответствует указанному регулярному выражению + /// Регулярное выражение, которому не должна соответствовать строка + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker DoesNotMatch([RegexPattern] string ExpectedRegEx, string? Message = null) => Checker.DoesNotMatch(new Regex(ExpectedRegEx), Message); - /// Проверка, что ссылка на строку не пуста и строка не является пустой - /// Объект проверки строкового значения - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker IsNotNullOrEmpty(this ValueChecker Checker, string? Message = null) - { - var str = Checker.ActualValue; - if (!string.IsNullOrEmpty(str)) return Checker; + /// Проверка, что строка НЕ соответствует указанному регулярному выражению + /// Регулярное выражение, которому не должна соответствовать строка + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker DoesNotMatch(Regex ExpectedRegEx, string? Message = null) + { + FormattableString msg = $"{Message.AddSeparator()}Указанная строка {Checker.ActualValue} ошибочно соответствует ожидаемому регулярному выражению {ExpectedRegEx}"; + StringAssert.DoesNotMatch(Checker.ActualValue, ExpectedRegEx, msg.ToStringInvariant()); + return Checker; + } - throw new AssertFailedException($"{Message.AddSeparator()}Строка является пустой {(str is null ? "ссылкой" : "строкой")}") + /// Проверка, что ссылка на строку не пуста и строка не является пустой + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker IsNotNullOrEmpty(string? Message = null) { - Data = { { "Actual", Checker.ActualValue } } - }; - } + var str = Checker.ActualValue; + if (!string.IsNullOrEmpty(str)) return Checker; - /// Проверка, что ссылка на строку пуста, либо строка пуста - /// Объект проверки строкового значения - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker IsNullOrEmpty(this ValueChecker Checker, string? Message = null) - { - var str = Checker.ActualValue; - if (!string.IsNullOrEmpty(str)) - throw new AssertFailedException($"{Message.AddSeparator()}Строка не пуста") + throw new AssertFailedException($"{Message.AddSeparator()}Строка является пустой {(str is null ? "ссылкой" : "строкой")}") { Data = { { "Actual", Checker.ActualValue } } }; - return Checker; - } + } - /// Проверка, что ссылка на строку не пуста и строка не является пустой, либо состоящей из пробелов - /// Объект проверки строкового значения - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker IsNotNullOrWhiteSpace(this ValueChecker Checker, string? Message = null) - { - var str = Checker.ActualValue; - if (string.IsNullOrWhiteSpace(str)) - throw new AssertFailedException($"{Message.AddSeparator()}Строка является {(str is null ? "пустой ссылкой" : string.IsNullOrWhiteSpace(str) ? "строкой из пробелов" : "пустой строкой")}") - { - Data = { { "Actual", Checker.ActualValue } } - }; - return Checker; - } + /// Проверка, что ссылка на строку пуста, либо строка пуста + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker IsNullOrEmpty(string? Message = null) + { + var str = Checker.ActualValue; + if (!string.IsNullOrEmpty(str)) + throw new AssertFailedException($"{Message.AddSeparator()}Строка не пуста") + { + Data = { { "Actual", Checker.ActualValue } } + }; + return Checker; + } - /// Проверка, что ссылка на строку пуста, либо строка пуста, либо строка состоит из пробелов - /// Объект проверки строкового значения - /// Сообщение, выводимое в случае ошибки при проверке - /// Исходный объект проверки строки - public static ValueChecker IsNullOrWhiteSpace(this ValueChecker Checker, string? Message = null) - { - var str = Checker.ActualValue; - if (!string.IsNullOrWhiteSpace(str)) - throw new AssertFailedException($"{Message.AddSeparator()}Строка не пуста") - { - Data = { { "Actual", Checker.ActualValue } } - }; - return Checker; + /// Проверка, что ссылка на строку не пуста и строка не является пустой, либо состоящей из пробелов + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker IsNotNullOrWhiteSpace(string? Message = null) + { + var str = Checker.ActualValue; + if (string.IsNullOrWhiteSpace(str)) + throw new AssertFailedException($"{Message.AddSeparator()}Строка является {(str is null ? "пустой ссылкой" : string.IsNullOrWhiteSpace(str) ? "строкой из пробелов" : "пустой строкой")}") + { + Data = { { "Actual", Checker.ActualValue } } + }; + return Checker; + } + + /// Проверка, что ссылка на строку пуста, либо строка пуста, либо строка состоит из пробелов + /// Сообщение, выводимое в случае ошибки при проверке + /// Исходный объект проверки строки + public ValueChecker IsNullOrWhiteSpace(string? Message = null) + { + var str = Checker.ActualValue; + if (!string.IsNullOrWhiteSpace(str)) + throw new AssertFailedException($"{Message.AddSeparator()}Строка не пуста") + { + Data = { { "Actual", Checker.ActualValue } } + }; + return Checker; + } } } \ No newline at end of file diff --git a/MathCore.TestsExtensions/Infrastructure/ExceptionEx.cs b/MathCore.TestsExtensions/Infrastructure/ExceptionEx.cs index fe36b67..ea0e18f 100644 --- a/MathCore.TestsExtensions/Infrastructure/ExceptionEx.cs +++ b/MathCore.TestsExtensions/Infrastructure/ExceptionEx.cs @@ -4,25 +4,26 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting.Infrastructure; internal static class ExceptionEx { - public static TException AddData(this TException exception, string Key, TValue value) - where TException : Exception + extension(TException exception) where TException : Exception { - if (value is null) - exception.Data[Key] = null; - else if (value.GetType().IsSerializable) - exception.Data[Key] = value; - return exception; - } + public TException AddData(string Key, TValue value) + { + if (value is null) + exception.Data[Key] = null; + else if (value.GetType().IsSerializable) + exception.Data[Key] = value; + return exception; + } - public static TException AddData(this TException exception, TValue value, [CallerArgumentExpression(nameof(value))] string? Key = null) - where TException : Exception - { - if (Key is not { Length: > 0 }) return exception; + public TException AddData(TValue value, [CallerArgumentExpression(nameof(value))] string? Key = null) + { + if (Key is not { Length: > 0 }) return exception; - if (value is null) - exception.Data[Key] = null; - else if (value.GetType().IsSerializable) - exception.Data[Key] = value; - return exception; + if (value is null) + exception.Data[Key] = null; + else if (value.GetType().IsSerializable) + exception.Data[Key] = value; + return exception; + } } } diff --git a/MathCore.TestsExtensions/Infrastructure/FormattableStringEx.cs b/MathCore.TestsExtensions/Infrastructure/FormattableStringEx.cs new file mode 100644 index 0000000..5691b25 --- /dev/null +++ b/MathCore.TestsExtensions/Infrastructure/FormattableStringEx.cs @@ -0,0 +1,12 @@ +using System.Runtime.CompilerServices; + +namespace Microsoft.VisualStudio.TestTools.UnitTesting.Infrastructure; + +internal static class FormattableStringEx +{ + extension(FormattableString str) + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public string ToStringInvariant() => str.ToString(CultureInfo.InvariantCulture); + } +} diff --git a/MathCore.TestsExtensions/MathCore.TestsExtensions.csproj b/MathCore.TestsExtensions/MathCore.TestsExtensions.csproj index b948f5a..f7dfde7 100644 --- a/MathCore.TestsExtensions/MathCore.TestsExtensions.csproj +++ b/MathCore.TestsExtensions/MathCore.TestsExtensions.csproj @@ -9,10 +9,8 @@ - 0.1.44 - - Методы-расширения для записи данных в System.Diagnostics.Trace - + 1.0.0 + Актуализация пакета и зависимостей, поддержка netstandard2.0 @@ -21,6 +19,11 @@ Библиотека средств помощи в процессе тестирования https://github.com/Infarh/MathCore.TestsExtensions https://github.com/Infarh/MathCore.TestsExtensions + git + true + true + true + portable UnitTest, MSTest Microsoft.VisualStudio.TestTools.UnitTesting shmachilin@yandex.ru @@ -29,8 +32,13 @@ MathCore.TestsExtensions.snk true snupkg + readme.md + + + + @@ -42,7 +50,8 @@ - + + diff --git a/MathCore.TestsExtensions/Properties/Annotations.cs b/MathCore.TestsExtensions/Properties/Annotations.cs index 009297a..79dd2a5 100644 --- a/MathCore.TestsExtensions/Properties/Annotations.cs +++ b/MathCore.TestsExtensions/Properties/Annotations.cs @@ -141,7 +141,7 @@ internal sealed class NotifyPropertyChangedInvocatorAttribute : Attribute public NotifyPropertyChangedInvocatorAttribute() { } public NotifyPropertyChangedInvocatorAttribute(string parameterName) => ParameterName = parameterName; - public string ParameterName { get; } + public string ParameterName { get; } = null!; } /// @@ -338,7 +338,7 @@ internal sealed class PublicAPIAttribute : Attribute public PublicAPIAttribute() { } public PublicAPIAttribute(string comment) => Comment = comment; - public string Comment { get; } + public string Comment { get; } = null!; } /// @@ -362,7 +362,7 @@ public class PathReferenceAttribute : Attribute public PathReferenceAttribute() { } public PathReferenceAttribute([PathReference] string basePath) => BasePath = basePath; - public string BasePath { get; } + public string BasePath { get; } = null!; } /// Является регулярным выражением diff --git a/MathCore.TestsExtensions/TraceEx.cs b/MathCore.TestsExtensions/TraceEx.cs index ce7cdd5..392eca7 100644 --- a/MathCore.TestsExtensions/TraceEx.cs +++ b/MathCore.TestsExtensions/TraceEx.cs @@ -5,8 +5,18 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; +/// Расширения трассировки для удобного вывода значений и перечислений в (категория "Tests") public static class TraceEx { + /// Выводит значение в трассировку () с указанием имени аргумента и возвращает его обратно + /// Тип значения + /// Значение для вывода + /// Имя выражения, переданное компилятором (если доступно) + /// Исходное значение без изменений + /// + /// Используется чтобы автоматически получить текст выражения аргумента. + /// Формат вывода: "Имя = Значение" если имя доступно, иначе просто "Значение". + /// public static T ToTrace(this T value, [CallerArgumentExpression(nameof(value))] string? Prefix = null) { Trace.WriteLine( @@ -17,6 +27,15 @@ public static T ToTrace(this T value, [CallerArgumentExpression(nameof(value) return value; } + /// Перечисляет элементы последовательности и выводит их значения в трассировку () c индексами + /// Тип элементов последовательности + /// Последовательность элементов для вывода + /// Имя выражения, переданное компилятором (если доступно) + /// + /// Если имя передано, выводит заголовок и заключает элементы в блок в виде массива. + /// Каждый элемент сопровождается комментарием с индексом: /*[индекс]*/ value. + /// Ширина поля индекса определяется количеством элементов (если доступно через ). + /// public static void ToTraceEnum(this IEnumerable items, [CallerArgumentExpression(nameof(items))] string? Name = null) { string? pad_str = null; @@ -43,5 +62,8 @@ public static void ToTraceEnum(this IEnumerable items, [CallerArgumentExpr Trace.WriteLine("]", "Tests"); } + /// Вычисляет целую часть десятичного логарифма положительного числа + /// Положительное целое число + /// Целая часть log10(x) private static int Log10Int(int x)=> (int)Math.Log10(x); } diff --git a/MathCore.TestsExtensions/readme.md b/MathCore.TestsExtensions/readme.md new file mode 100644 index 0000000..b88caae --- /dev/null +++ b/MathCore.TestsExtensions/readme.md @@ -0,0 +1,130 @@ +# MathCore.TestsExtensions + + MSTest, fluent- : +- `Assert.That` +- `CollectionAssert.That` +- `StringAssert.That` + + API: , , , . + +## + +- : .NET Standard 2.0 +- : MSTest.TestFramework >= 4.0.2 + +NuGet-: MathCore.TestsExtensions + +## + +```csharp +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class SampleTests +{ + [TestMethod] + public void Value_and_Collections() + { + Assert.That.Value(42).IsEqual(42); + + var items = new[] { 1, 3, 5, 7 }; + Assert.That.Collection(items) + .IsNotEmpty() + .Contains(5) + .IsEqualTo(1, 3, 5, 7); + } +} +``` + +## fluent- + + `That` : +- `Assert.That` (`Value`), / (`Method`), (`Enumerable`) (`Collection`) +- `CollectionAssert.That` (`Collection`) +- `StringAssert.That` `Value(string)` + + : , -. `And => Assert.That`, . + +### : Assert.That + + : +```csharp +Assert.That.Value(1.1).LessOrEqualsThan(1.0, 0.1); +Assert.That.Value(10).GreaterThan(5); +``` + + : +```csharp +Assert.That.Method(() => throw new InvalidOperationException()) + .Throw(); + +Assert.That.Method(() => 1 / 0) + .Throw(); +``` + + (`IEnumerable`): +```csharp +IEnumerable actual = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; +IEnumerable expected = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; + +Assert.That.Enumerable(actual).IsEqualTo(expected); +Assert.That.Enumerable(actual).Contains(s => s.EndsWith(".txt")); +``` + +### : CollectionAssert.That + + `ICollection` : +```csharp +var items = new[] { 1, 3, 5, 7 }; + +CollectionAssert.That.Collection(items) + .IsItemsCount(4) + .Contains(5) + .IsEqualTo(1, 3, 5, 7); + +var expected = new[] { 1, 3, 5, 7 }; +CollectionAssert.That.Collection(items).IsEqualTo(expected); +``` + + double: +```csharp +double[] actual = { 1.0, 2.0, 3.000000001 }; +double[] expected = { 1.0, 2.0, 3.0 }; + +Assert.That.Collection(actual).IsEqualTo(expected, 1e-8); +``` + +### : StringAssert.That + + `ValueChecker`: +```csharp +StringAssert.That.Value("Hello, World!") + .StartWith("Hello") + .Contains("World") + .EndWith("!") + .Matches(@"^Hello,\sWorld!$"); +``` + +## : / + + : +```csharp +var xs = Enumerable.Range(0, 10).ToArray(); + +Assert.That.Collection(xs) + .ItemsCount.IsEqual(10) + .AllItems((v, i) => v.IsEqual(i)); + +Assert.That.Enumerable(xs) + .Max(x => x).IsEqual(9) + .Min(x => x).IsEqual(0) + .Average(x => x).IsEqual(4.5); +``` + +## + + : ( ), `Expected` `Actual` `Exception.Data`. + +## + +MIT diff --git a/README.md b/README.md new file mode 100644 index 0000000..b10780f --- /dev/null +++ b/README.md @@ -0,0 +1,135 @@ +# MathCore.TestsExtensions + +Расширения для MSTest, добавляющие удобный fluent-интерфейс к стандартным ассертам. Библиотека предоставляет точки расширения `Assert.That`, `CollectionAssert.That` и `StringAssert.That`, позволяющие писать выразительные, компактные и читаемые проверки без потери информативности сообщений об ошибках. + +- Целевая платформа: .NET Standard 2.0 (работает в большинстве тестовых проектов на современном .NET) +- Зависимости: MSTest.TestFramework ≥ 4.0.2 +- Лицензия: MIT + +## Возможности + +- Fluent-интерфейс для проверок значений, коллекций, перечислений и строк +- Расширения: `Assert.That`, `CollectionAssert.That`, `StringAssert.That` +- Чекеры: + - `ValueChecker` и специализированный `DoubleValueChecker` (сравнения с точностью, границы, преобразования типов) + - `CollectionChecker` и `EnumerableChecker` (поэлементное сравнение, позиционные проверки, агрегаты `Max/Min/Average`, проверки наличия/отсутствия элементов) + - Поддержка точности для числовых типов и информативные отчёты о расхождениях (включая относительную ошибку) +- Проверки исключений для методов/функций: `Assert.That.Method(...).Throw()` +- Строковые проверки через `StringAssert.That.Value(string)` с `StartWith`, `EndWith`, `Contains`, `Matches`, `DoesNotMatch`, `Is(Not)NullOr(White)Space` +- Понятные сообщения об ошибках с указанием индексов и сводок по различиям, а также данными `Expected/Actual` в `Exception.Data` +- Утилиты для логирования результатов теста: `TestResultExtensions` (`LogWriteLine`, `ToDebug`, `ToDebugEnum`) + +## Установка + +NuGet-пакет: MathCore.TestsExtensions + +Пример установки: + +```powershell +# PackageReference +Install-Package MathCore.TestsExtensions + +# dotnet CLI +dotnet add package MathCore.TestsExtensions +``` + +## Быстрый старт + +```csharp +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class SampleTests +{ + [TestMethod] + public void Values_and_Collections() + { + Assert.That.Value(42).IsEqual(42); + + var items = new[] { 1, 3, 5, 7 }; + Assert.That.Collection(items) + .IsNotEmpty() + .Contains(5) + .IsEqualTo(1, 3, 5, 7); + } +} +``` + +## Точки расширения и fluent-паттерны + +- `Assert.That` + - `Value(T)`, `Value(double)` — проверки значений и чисел с учётом точности + - `Method(Action/Func)` — проверки исключений + - `Enumerable(IEnumerable)` — проверки перечислений + - `Collection(ICollection/T[])` — проверки коллекций +- `CollectionAssert.That` + - `Collection(…)` — проверки `ICollection`, массивов и специальных форматов (включая `double[,]`) +- `StringAssert.That` + - `Value(string)` — строковые проверки и проверки по регулярным выражениям + +Каждый чекер поддерживает цепочки и имеет свойство `And => Assert.That`, упрощающее продолжение проверок. + +## Примеры + +Значения и точность: +```csharp +Assert.That.Value(1.1).LessOrEqualsThan(1.0, 0.1); +Assert.That.Value(10).GreaterThan(5); +``` + +Исключения: +```csharp +Assert.That.Method(() => throw new InvalidOperationException()) + .Throw(); +``` + +Перечисления: +```csharp +IEnumerable actual = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; +IEnumerable expected = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; + +Assert.That.Enumerable(actual) + .IsEqualTo(expected) + .Contains(s => s.EndsWith(".txt")); +``` + +Коллекции: +```csharp +var items = new[] { 1, 3, 5, 7 }; +var expected = new[] { 1, 3, 5, 7 }; + +CollectionAssert.That.Collection(items) + .IsItemsCount(4) + .Contains(5) + .IsEqualTo(expected); +``` + +Строки: +```csharp +StringAssert.That.Value("Hello, World!") + .StartWith("Hello") + .Contains("World") + .EndWith("!") + .Matches(@"^Hello,\sWorld!$"); +``` + +## Структура репозитория + +- `MathCore.TestsExtensions/` — библиотека (`MathCore.TestsExtensions.csproj`), сборка пакета NuGet +- `Tests/MathCore.TestsExtensions.Tests/` — модульные тесты (`MathCore.TestsExtensions.Tests.csproj`) +- `.github/workflows/` — CI-пайплайны для тестирования и публикации + +## CI/CD + +- Тестирование и сборка выполняются в GitHub Actions (`.github/workflows/testing.yml`) +- Публикация пакета в NuGet через GitHub Actions (`.github/workflows/publish.yml`) +- В пакете включены символы и SourceLink для удобной отладки + +## Обратная связь и вклад + +- Идеи и баг-репорты — через Issues +- PR приветствуются: тесты, улучшение сообщений об ошибках, новые fluent-проверки + +## Лицензия + +MIT \ No newline at end of file diff --git a/Tests/MathCore.TestsExtensions.Tests/AssertTests.cs b/Tests/MathCore.TestsExtensions.Tests/AssertTests.cs index 1ce2f0e..643907e 100644 --- a/Tests/MathCore.TestsExtensions.Tests/AssertTests.cs +++ b/Tests/MathCore.TestsExtensions.Tests/AssertTests.cs @@ -15,6 +15,7 @@ protected static TException ExpectedException(Action AssertAction) w { expected_exception = exception; } + if (expected_exception is null) throw new AssertFailedException($"Требуемое исключение типа {typeof(TException).Name} выброшено не было"); diff --git a/Tests/MathCore.TestsExtensions.Tests/AssertThatCollectionTests.cs b/Tests/MathCore.TestsExtensions.Tests/AssertThatCollectionTests.cs index ccc711d..4b5b6be 100644 --- a/Tests/MathCore.TestsExtensions.Tests/AssertThatCollectionTests.cs +++ b/Tests/MathCore.TestsExtensions.Tests/AssertThatCollectionTests.cs @@ -1,5 +1,6 @@ // ReSharper disable PossibleMultipleEnumeration +// ReSharper disable InconsistentNaming namespace MathCore.TestsExtensions.Tests; [TestClass] diff --git a/Tests/MathCore.TestsExtensions.Tests/AssertThatEnumerableTests.cs b/Tests/MathCore.TestsExtensions.Tests/AssertThatEnumerableTests.cs index 48919b8..e7f1c3d 100644 --- a/Tests/MathCore.TestsExtensions.Tests/AssertThatEnumerableTests.cs +++ b/Tests/MathCore.TestsExtensions.Tests/AssertThatEnumerableTests.cs @@ -6,8 +6,8 @@ public class AssertThatEnumerableTests : AssertTests [TestMethod] public void IsEqualTo_Success() { - IEnumerable actual = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; - IEnumerable expected = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; + IEnumerable actual = ["file3.txt", "file4.txt", "file5.txt", "file6.txt"]; + IEnumerable expected = ["file3.txt", "file4.txt", "file5.txt", "file6.txt"]; Assert.That.Enumerable(actual).IsEqualTo(expected); } @@ -15,8 +15,8 @@ public void IsEqualTo_Success() [TestMethod] public void IsEqualTo_Fail_DifferentValues() { - IEnumerable actual = new[] { "file3.txt", "file4.txt", "-------", "file6.txt" }; - IEnumerable expected = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; + IEnumerable actual = ["file3.txt", "file4.txt", "-------", "file6.txt"]; + IEnumerable expected = ["file3.txt", "file4.txt", "file5.txt", "file6.txt"]; try { @@ -32,8 +32,8 @@ public void IsEqualTo_Fail_DifferentValues() [TestMethod] public void IsEqualTo_Fail_DifferentCount() { - IEnumerable actual = new[] { "file3.txt", "file4.txt", "file5.txt" }; - IEnumerable expected = new[] { "file3.txt", "file4.txt", "file5.txt", "file6.txt" }; + IEnumerable actual = ["file3.txt", "file4.txt", "file5.txt"]; + IEnumerable expected = ["file3.txt", "file4.txt", "file5.txt", "file6.txt"]; try { diff --git a/Tests/MathCore.TestsExtensions.Tests/ExtensionsTests.cs b/Tests/MathCore.TestsExtensions.Tests/ExtensionsTests.cs index 19bc794..eb781bb 100644 --- a/Tests/MathCore.TestsExtensions.Tests/ExtensionsTests.cs +++ b/Tests/MathCore.TestsExtensions.Tests/ExtensionsTests.cs @@ -14,9 +14,9 @@ public void SuccessesTest() var list = new List(); Assert.That.Value(list) .AssertThat(l => l.IsNotNull()) - .Where(l => l.Count) + .Where(l => l!.Count) .Check(Count => Count.IsEqual(0)) - .Where(l => l.Capacity) + .Where(l => l!.Capacity) .Check(Capacity => Capacity.IsEqual(0)); } diff --git a/Tests/MathCore.TestsExtensions.Tests/MathCore.TestsExtensions.Tests.csproj b/Tests/MathCore.TestsExtensions.Tests/MathCore.TestsExtensions.Tests.csproj index cc2068a..0f25a52 100644 --- a/Tests/MathCore.TestsExtensions.Tests/MathCore.TestsExtensions.Tests.csproj +++ b/Tests/MathCore.TestsExtensions.Tests/MathCore.TestsExtensions.Tests.csproj @@ -1,17 +1,17 @@  - net8.0 + net10.0 true false enable - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Tests/MathCore.TestsExtensions.Tests/Properties/AssemblyInfo.cs b/Tests/MathCore.TestsExtensions.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..748df43 --- /dev/null +++ b/Tests/MathCore.TestsExtensions.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: Parallelize(Workers = 4, Scope = ExecutionScope.MethodLevel)] \ No newline at end of file