-
Notifications
You must be signed in to change notification settings - Fork 57
Глейзер Роман #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Глейзер Роман #39
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| using NUnit.Framework; | ||
| using FluentAssertions; | ||
| using NUnit.Framework; | ||
| using NUnit.Framework.Legacy; | ||
|
|
||
| namespace HomeExercise.Tasks.ObjectComparison; | ||
| public class ObjectComparison | ||
|
|
||
| public class TsarComparison | ||
| { | ||
| [Test] | ||
| [Description("Проверка текущего царя")] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. категорию теста после рефакторинга можно убрать |
||
|
|
@@ -11,31 +13,63 @@ public void CheckCurrentTsar() | |
| { | ||
| var actualTsar = TsarRegistry.GetCurrentTsar(); | ||
|
|
||
| var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, | ||
| new Person("Vasili III of Russia", 28, 170, 60, null)); | ||
| var expectedTsar = new Person( | ||
| name: "Ivan IV The Terrible", | ||
| age: 54, | ||
| height: 170, | ||
| weight: 70, | ||
| parent: new Person( | ||
| name: "Vasili III of Russia", | ||
| age: 28, | ||
| height: 170, | ||
| weight: 60, | ||
| parent: null! | ||
| ) | ||
| ); | ||
|
|
||
| // Перепишите код на использование Fluent Assertions. | ||
| ClassicAssert.AreEqual(actualTsar.Name, expectedTsar.Name); | ||
| ClassicAssert.AreEqual(actualTsar.Age, expectedTsar.Age); | ||
| ClassicAssert.AreEqual(actualTsar.Height, expectedTsar.Height); | ||
| ClassicAssert.AreEqual(actualTsar.Weight, expectedTsar.Weight); | ||
| /// <summary> | ||
| /// Такой подход автоматически проверяет все свойства объекта, включая вложенные | ||
| /// Тест не будет требовать изменений при добавлении новых свойств в класс Person | ||
| /// При падении теста, FluentAssertions предоставляет подробную информацию о том, какие именно свойства не совпали | ||
| /// </summary> | ||
|
|
||
| ClassicAssert.AreEqual(expectedTsar.Parent!.Name, actualTsar.Parent!.Name); | ||
| ClassicAssert.AreEqual(expectedTsar.Parent.Age, actualTsar.Parent.Age); | ||
| ClassicAssert.AreEqual(expectedTsar.Parent.Height, actualTsar.Parent.Height); | ||
| ClassicAssert.AreEqual(expectedTsar.Parent.Parent, actualTsar.Parent.Parent); | ||
| actualTsar.Should().BeEquivalentTo(expectedTsar, options => options.Excluding(t => t.Id).Excluding(t => t.Parent.Id)); | ||
| } | ||
|
|
||
| [Test] | ||
| [Description("Альтернативное решение. Какие у него недостатки?")] | ||
| public void CheckCurrentTsar_WithCustomEquality() | ||
| { | ||
| var actualTsar = TsarRegistry.GetCurrentTsar(); | ||
| var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, | ||
| new Person("Vasili III of Russia", 28, 170, 60, null)); | ||
|
|
||
| // Какие недостатки у такого подхода? | ||
|
|
||
| var expectedTsar = new Person( | ||
| name: "Ivan IV The Terrible", | ||
| age: 54, | ||
| height: 170, | ||
| weight: 70, | ||
| new Person( | ||
| name: "Vasili III of Russia", | ||
| age: 28, | ||
| height: 170, | ||
| weight: 60, | ||
| parent: null! | ||
| ) | ||
| ); | ||
|
|
||
| // Какие недостатки у такого подхода? | ||
| // Недостатки подхода: | ||
| // 1) Требуется ручное обновление метода сравнения при добавлении новых свойств в класс Person, | ||
| // 2) Тест менее информативен при падении. Он просто укажет, что объекты не равны, не показывая какие именно свойства не совпали. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Могут ли быть проблемы с рекурсией?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| ClassicAssert.True(AreEqual(actualTsar, expectedTsar)); | ||
|
|
||
| // Вызываем Stack Overflow exception | ||
| // var p1 = new Person("A", 1, 1, 1, null!); | ||
| // p1.Parent = p1; | ||
| // | ||
| // var p2 = new Person("A", 1, 1, 1, null!); | ||
| // p2.Parent = p2; | ||
| // | ||
| // ClassicAssert.True(AreEqual(p1, p2)); | ||
| } | ||
|
|
||
| private bool AreEqual(Person? actual, Person? expected) | ||
|
|
@@ -49,4 +83,4 @@ private bool AreEqual(Person? actual, Person? expected) | |
| && actual.Weight == expected.Weight | ||
| && AreEqual(actual.Parent, expected.Parent); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,209 @@ | ||
| | ||
| using FluentAssertions; | ||
| using NUnit.Framework; | ||
| using NUnit.Framework.Legacy; | ||
|
|
||
| namespace HomeExercise.Tasks.NumberValidator; | ||
|
|
||
| [TestFixture] | ||
| public class NumberValidatorTests | ||
| { | ||
| #region Допустимая разрядность | ||
|
|
||
| [TestCase(-1, 2, true)] | ||
| [TestCase(0, 2, true)] | ||
| public void Ctor_InvalidPrecision_ThrowsArgumentException(int precision, int scale, bool onlyPositive) | ||
| { | ||
| var act = () => new NumberValidator(precision, scale, onlyPositive); | ||
| act.Should() | ||
| .Throw<ArgumentException>() | ||
| .WithMessage("precision must be a positive number"); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Некорректная дробность | ||
|
|
||
| [TestCase(5, -1, true)] | ||
| public void Ctor_InvalidScale_Negative_ThrowsArgumentException(int precision, int scale, bool onlyPositive) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если TestCase один, то лучше не писать через TestCase, а написать просто тест |
||
| { | ||
| var act = () => new NumberValidator(precision, scale, onlyPositive); | ||
| act.Should() | ||
| .Throw<ArgumentException>() | ||
| .WithMessage("*non-negative*"); // узнал, что можно передавать часть строки | ||
| } | ||
|
|
||
| [TestCase(1, 2, true)] | ||
| [TestCase(1, 1, true)] | ||
| public void Ctor_WithScaleGreaterOrEqualToPrecision_ThrowsArgumentException(int precision, int scale, bool onlyPositive) | ||
| { | ||
| var act = () => new NumberValidator(precision, scale, onlyPositive); | ||
| act.Should() | ||
| .Throw<ArgumentException>() | ||
| .WithMessage("*less or equal*"); // узнал, что можно передавать часть строки | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Корректные аргументы для конструктора | ||
|
|
||
| [Test] | ||
| public void Ctor_ValidArguments_DoesNotThrow() | ||
| { | ||
| var act = () => new NumberValidator(1, 0, true); | ||
| act.Should().NotThrow(); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Передаваемое число в формате пустой строки или null | ||
|
|
||
| [TestCase("", 17, 2, true)] | ||
| [TestCase(null, 17, 2, true)] | ||
| public void IsValidNumber_NullOrEmpty_ReturnsFalse(string value, int precision, int scale, bool onlyPositive) | ||
| { | ||
| var validator = new NumberValidator(precision, scale, onlyPositive); | ||
| var result = validator.IsValidNumber(value); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Некорректный формат передаваемого числа | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_MultipleFractionSeparators_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(10, 4, true); | ||
| var result = validator.IsValidNumber("1..2"); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_OnlySigns_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(15, 1, true); | ||
| var result = validator.IsValidNumber("+-."); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_OnlyDot_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(22, 8, true); | ||
| var result = validator.IsValidNumber("."); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_DotLastSign_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(9, 4, true); | ||
| var result = validator.IsValidNumber("1."); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_DotFirstSign_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(7, 3, true); | ||
| var result = validator.IsValidNumber(".1"); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_ContainsSpace_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(17, 6, true); | ||
| var result = validator.IsValidNumber("5 2"); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Test() | ||
| { | ||
| Assert.Throws<ArgumentException>(() => new NumberValidator(-1, 2, true)); | ||
| Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); | ||
| Assert.Throws<ArgumentException>(() => new NumberValidator(-1, 2, false)); | ||
| Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); | ||
|
|
||
| ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); | ||
| ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0")); | ||
| ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); | ||
| ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("00.00")); | ||
| ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-0.00")); | ||
| ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); | ||
| ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+0.00")); | ||
| ClassicAssert.IsTrue(new NumberValidator(4, 2, true).IsValidNumber("+1.23")); | ||
| ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+1.23")); | ||
| ClassicAssert.IsFalse(new NumberValidator(17, 2, true).IsValidNumber("0.000")); | ||
| ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-1.23")); | ||
| ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("a.sd")); | ||
| public void IsValidNumber_ContainsUnderscore_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(11, 3, true); | ||
| var result = validator.IsValidNumber("4_4"); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_ContainsLettersAndUnderscore_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(10, 5, true); | ||
| var result = validator.IsValidNumber("abcd_4"); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsValidNumber_DoubleMinus_ReturnsFalse() | ||
| { | ||
| var validator = new NumberValidator(12, 2, true); | ||
| var result = validator.IsValidNumber("--1"); | ||
| result.Should().BeFalse(); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Корректное передаваемое число | ||
|
|
||
| [TestCase("+1", 4, 2, true)] | ||
| [TestCase("+0.1", 9, 1, true)] | ||
| [TestCase("000.10", 5, 2, true)] | ||
| [TestCase("000,10", 8, 4, true)] | ||
| [TestCase("10", 2, 0, true)] | ||
| public void IsValidNumber_ValidFormat_ReturnsTrue(string value, int precision, int scale, bool onlyPositive) | ||
| { | ||
| var validator = new NumberValidator(precision, scale, onlyPositive); | ||
| var result = validator.IsValidNumber(value); | ||
| result.Should().BeTrue(); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Количество допустимых цифр в числе, включая знак, целую и дробную часть, без точки | ||
|
|
||
| [TestCase("17.9", 3, 1, true, true)] | ||
| [TestCase("171.9", 3, 1, true, false)] | ||
| [TestCase("+17", 3, 2, true, true)] | ||
| [TestCase("+17", 2, 0, true, false)] | ||
| public void IsValidNumber_RespectsPrecisionLimit_ReturnsExpected(string value, int precision, int scale, | ||
| bool onlyPositive, bool expected) | ||
| { | ||
| var validator = new NumberValidator(precision, scale, onlyPositive); | ||
| var result = validator.IsValidNumber(value); | ||
| result.Should().Be(expected); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Количество знаков после запятой | ||
|
|
||
| [TestCase("1.0", 10, 0, true, false)] | ||
| [TestCase("1.44", 10, 2, true, true)] | ||
| [TestCase("1.4", 10, 2, true, true)] | ||
| [TestCase("1,040", 10, 3, true, true)] | ||
| [TestCase("1.41414141", 10, 2, true, false)] | ||
| public void IsValidNumber_RespectsScale_ReturnsExpected(string value, int precision, int scale, bool onlyPositive, | ||
| bool expected) | ||
| { | ||
| var validator = new NumberValidator(precision, scale, onlyPositive); | ||
| var result = validator.IsValidNumber(value); | ||
| result.Should().Be(expected); | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region Проверка параметра onlyPositive (только положительные) | ||
|
|
||
| [TestCase("-4.59", 4, 2, false, true)] | ||
| [TestCase("-6", 2, 0, true, false)] | ||
| [TestCase("+5", 2, 0, false, true)] | ||
| public void IsValidNumber_RespectsOnlyPositive_ReturnsExpected(string value, int precision, int scale, bool onlyPositive, | ||
| bool expected) | ||
| { | ||
| var validator = new NumberValidator(precision, scale, onlyPositive); | ||
| var result = validator.IsValidNumber(value); | ||
| result.Should().Be(expected); | ||
| } | ||
|
|
||
| #endregion | ||
| } | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Неинформативное название и описание. Не ясно что проверяется. Давай поправим