diff --git a/cs/HomeExercises/NumberValidatorTests.cs b/cs/HomeExercises/NumberValidatorTests.cs index a2878113..2d660268 100644 --- a/cs/HomeExercises/NumberValidatorTests.cs +++ b/cs/HomeExercises/NumberValidatorTests.cs @@ -1,32 +1,110 @@ using System; +using System.Collections; +using System.Linq; using System.Text.RegularExpressions; using FluentAssertions; using NUnit.Framework; namespace HomeExercises { + [TestFixture] public class NumberValidatorTests { - [Test] - public void Test() + public static TestCaseData[] unsignedPositiveNumberTestCases = { - Assert.Throws(() => new NumberValidator(-1, 2, true)); - Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); - Assert.Throws(() => new NumberValidator(-1, 2, false)); - Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); - - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0")); - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("00.00")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-0.00")); - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+0.00")); - Assert.IsTrue(new NumberValidator(4, 2, true).IsValidNumber("+1.23")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+1.23")); - Assert.IsFalse(new NumberValidator(17, 2, true).IsValidNumber("0.000")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-1.23")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("a.sd")); + new TestCaseData(1, 0, "0").SetName("When_UnsignedZero"), + new TestCaseData(2, 1, "0.0").SetName("When_UnsignedZero_WithOneDigitAfter"), + new TestCaseData(1, 0, "1").SetName("When_UnsignedOneDigitNumber"), + new TestCaseData(2, 0, "12").SetName("When_UnsignedTwoDigitNumber"), + new TestCaseData(2, 1, "1.2").SetName("When_UnsignedTwoDigitNumber_WithOneDigitAfterPoint"), + new TestCaseData(3, 2, "1.23").SetName("When_UnsignedThreeDigitNumber_WithTwoDigitsAfterPoint"), + new TestCaseData(3, 1, "12.3").SetName("When_UnsignedThreeDigitNumber_WithOneDigitAfterPoint"), + new TestCaseData(4, 2, "12.34").SetName("When_UnsignedFourDigitNumber_WithTwoDigitsAfterPoint"), + }; + + public static TestCaseData[] signedPositiveNumberTestCases = + { + new TestCaseData(2, 0, "+0").SetName("When_PositiveZero"), + new TestCaseData(3, 1, "+0.0").SetName("When_PositiveZero_WithOneDigitAfter"), + new TestCaseData(2, 0, "+1").SetName("When_PositiveOneDigitNumber"), + new TestCaseData(3, 0, "+12").SetName("When_PositiveTwoDigitNumber"), + new TestCaseData(3, 1, "+1.2").SetName("When_PositiveTwoDigitNumber_WithOneDigitAfterPoint"), + new TestCaseData(4, 2, "+1.23").SetName("When_PositiveThreeDigitNumber_WithTwoDigitsAfterPoint"), + new TestCaseData(4, 1, "+12.3").SetName("When_PositiveThreeDigitNumber_WithOneDigitAfterPoint"), + new TestCaseData(5, 2, "+12.34").SetName("When_PositiveFourDigitNumber_WithTwoDigitsAfterPoint"), + }; + + public static TestCaseData[] negativeNumberTestCases = + { + new TestCaseData(2, 0, "-0").SetName("When_NegativeZero"), + new TestCaseData(3, 1, "-0.0").SetName("When_NegativeZero_WithOneDigitAfter"), + new TestCaseData(2, 0, "-1").SetName("When_NegativeOneDigitNumber"), + new TestCaseData(3, 0, "-12").SetName("When_NegativeTwoDigitNumber"), + new TestCaseData(3, 1, "-1.2").SetName("When_NegativeTwoDigitNumber_WithOneDigitAfterPoint"), + new TestCaseData(4, 2, "-1.23").SetName("When_NegativeThreeDigitNumber_WithTwoDigitsAfterPoint"), + new TestCaseData(4, 1, "-12.3").SetName("When_NegativeThreeDigitNumber_WithOneDigitAfterPoint"), + new TestCaseData(5, 2, "-12.34").SetName("When_NegativeFourDigitNumber_WithTwoDigitsAfterPoint"), + }; + + public static TestCaseData[] wrongCases = + { + new TestCaseData(1, 0, "-1") + .SetName("When_NegativeIntegerNumber_HavePrecisionLesserOrEqual_ThanDigitsCount").Returns(false), + new TestCaseData(1, 0, "+1") + .SetName("When_PositiveIntegerNumber_HavePrecisionLesserOrEqual_ThanDigitsCount").Returns(false), + new TestCaseData(2, 1, "+1.2") + .SetName("When_PositiveNumberWithFractionalPart_HavePrecisionLesserOrEqual_ThanDigitsCount") + .Returns(false), + new TestCaseData(2, 1, "-1.2") + .SetName("When_NegativeNumberWithFractionalPart_HavePrecisionLesserOrEqual_ThanDigitsCount") + .Returns(false), + }; + + [TestCaseSource(nameof(unsignedPositiveNumberTestCases))] + [TestCaseSource(nameof(signedPositiveNumberTestCases))] + [TestCaseSource(nameof(negativeNumberTestCases))] + public void IsValidNumber(int precision, int scale, string validatingString) + { + new NumberValidator(precision, scale) + .IsValidNumber(validatingString) + .Should() + .BeTrue(); + } + + [TestCaseSource(nameof(wrongCases))] + public bool IsNotValidNumber(int precision, int scale, string validatingString) + { + return new NumberValidator(precision, scale).IsValidNumber(validatingString); + } + + [TestCaseSource(nameof(negativeNumberTestCases))] + public void IsFailWithOnlyPositiveFlag(int precision, int scale, string validatingString) + { + new NumberValidator(precision, scale, true) + .IsValidNumber(validatingString) + .Should() + .BeFalse(); + } + + [TestCase(3, 2, "a.sd", TestName = "WhenContain_NonDigitSymbols")] + [TestCase(2, 1, ".0", TestName = "WhenHaveNot_DigitBeforePoint")] + [TestCase(1, 0, "0.", TestName = "WhenHaveNot_DigitAfterPointIfExist")] + public void IsWrongFormat(int precision, int scale, string validatingString, bool onlyPositive = true) + { + new NumberValidator(precision, scale, onlyPositive) + .IsValidNumber(validatingString) + .Should() + .BeFalse(); + } + + [TestCase(-1, 1, TestName = "When_NegativePrecision")] + [TestCase(1, -1, TestName = "When_NegativeScale")] + [TestCase(-1, -1, TestName = "When_NegativePrecisionAndScale")] + [TestCase(1, 1, TestName = "When_PrecisionEqualsScale")] + [TestCase(1, 2, TestName = "When_PrecisionLessThanScale")] + public void ShouldThrow(int precision, int scale, bool onlyPositive = true) + { + Assert.Throws(() => new NumberValidator(precision, scale, onlyPositive)); } } diff --git a/cs/HomeExercises/ObjectComparison.cs b/cs/HomeExercises/ObjectComparison.cs index 44d9aed4..13949f03 100644 --- a/cs/HomeExercises/ObjectComparison.cs +++ b/cs/HomeExercises/ObjectComparison.cs @@ -1,4 +1,6 @@ -using FluentAssertions; +using System; +using FluentAssertions; +using FluentAssertions.Equivalency; using NUnit.Framework; namespace HomeExercises @@ -16,15 +18,13 @@ public void CheckCurrentTsar() new Person("Vasili III of Russia", 28, 170, 60, null)); // Перепишите код на использование Fluent Assertions. - Assert.AreEqual(actualTsar.Name, expectedTsar.Name); - Assert.AreEqual(actualTsar.Age, expectedTsar.Age); - Assert.AreEqual(actualTsar.Height, expectedTsar.Height); - Assert.AreEqual(actualTsar.Weight, expectedTsar.Weight); - - Assert.AreEqual(expectedTsar.Parent!.Name, actualTsar.Parent!.Name); - Assert.AreEqual(expectedTsar.Parent.Age, actualTsar.Parent.Age); - Assert.AreEqual(expectedTsar.Parent.Height, actualTsar.Parent.Height); - Assert.AreEqual(expectedTsar.Parent.Parent, actualTsar.Parent.Parent); + actualTsar.Should().BeEquivalentTo(expectedTsar, options => + options + .IgnoringCyclicReferences() + .Excluding((IMemberInfo info) => + info.SelectedMemberInfo.DeclaringType == typeof(Person) + && info.SelectedMemberInfo.Name == nameof(Person.Id)) + ); } [Test] @@ -35,7 +35,15 @@ public void CheckCurrentTsar_WithCustomEquality() var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); + // Какие недостатки у такого подхода? + + // 1. Вероятность StackOverflow из-за бесконечной рекурсии + // 2. При каждом изменении свойств или добавлении новых функцию придётся переписывать + // 3. Нарушение SRP, ответственность за сравнение объетов должна быть инкапсулирована в класс + // 4. Тест не показывает, по каким критериям различаются два объекта + // 5. Название теста не говорит о конкрутных различиях этого теста с предыдущим + Assert.True(AreEqual(actualTsar, expectedTsar)); }