Skip to content
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

Леонтьев Дмитрий #19

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
74 changes: 72 additions & 2 deletions Testing/Basic/Classwork/1. WordsStatistics/WordsStatisticsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ namespace Basic.Task.WordsStatistics;
[TestFixture]
public class WordsStatisticsTests
{

private IWordsStatistics wordsStatistics;

[SetUp]
public void SetUp()
{

wordsStatistics = CreateStatistics();
}

Expand Down Expand Up @@ -46,4 +44,76 @@ public void GetStatistics_ContainsManyItems_AfterAdditionOfDifferentWords()
wordsStatistics.AddWord("def");
wordsStatistics.GetStatistics().Should().HaveCount(2);
}

[Test]
public void GetStatistics_ThrowArgumentNullException_AfterAdditionNull()
{
wordsStatistics
.Invoking(word => word.AddWord(null))
.Should()
.Throw<ArgumentNullException>()
.WithMessage("Value cannot be null. (Parameter 'word')");
}

[Test]
public void GetStatistics_IsEmpty_AfterAdditionWhiteSpaceString()
{
wordsStatistics.AddWord(" ");
wordsStatistics.GetStatistics().Should().BeEmpty();
}

[Test]
public void GetStatistics_LengthWord_AfterAdditionStringLongerThenTen()
{
wordsStatistics.AddWord("very long string");
wordsStatistics.GetStatistics().Should().Equal(new WordCount("very long ", 1));
}

[Test]
public void GetStatistics_Count_AfterAdditionSameWord()
{
for (var i = 0; i < 3; i++)
{
wordsStatistics.AddWord("word");
}

wordsStatistics.GetStatistics().First().Count.Should().Be(3);
}

[Test]
public void GetStatistics_TypeOfWordCount_AfterAdditionWord()
{
wordsStatistics.AddWord("word");

wordsStatistics.GetStatistics().First().GetType().Should().Be(typeof(WordCount));
}

[Test]
public void GetStatistics_IsLowerWord_AfterAdditionWord()
{
wordsStatistics.AddWord("WORD");

wordsStatistics.GetStatistics().First().Word.Should().Be("word");
}

[Test]
public void GetStatistics_OrderByDescending_AfterAdditionDifferentWords()
{
wordsStatistics.AddWord("word3");

for (var i = 0; i < 2; i++)
{
wordsStatistics.AddWord("word2");
}

for (var i = 0; i < 3; i++)
{
wordsStatistics.AddWord("word1");
}

wordsStatistics
.GetStatistics()
.Should()
.Equal(new List<WordCount>{new ("word1", 3), new ("word2", 2), new ("word3", 1)});
}
}
3 changes: 2 additions & 1 deletion Testing/Basic/Classwork/2. TDD/Game.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
namespace TDD.Task;
public class Game
{
private int score = 0;
public void Roll(int pins)
{
throw new NotImplementedException();
}

public int GetScore()
{
throw new NotImplementedException();
return score;
}
}

Expand Down
33 changes: 19 additions & 14 deletions Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
using NUnit.Framework;
using NUnit.Framework.Legacy;
using FluentAssertions;

namespace HomeExercise.Tasks.ObjectComparison;

public class ObjectComparison
{
[Test]
[Description("Проверка текущего царя")]
[Category("ToRefactor")]
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));

// Перепишите код на использование 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);

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
.AllowingInfiniteRecursion()
.Excluding(o => o.DeclaringType == typeof(Person) && o.Name == nameof(Person.Id)));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Теперь окей. При сравнении объектового графа еще иногда полезно игнорировать циклические ссылки. Но в данном случае это не обязательно, тут по бизнеслогике цари в династии повторяться не должны вроде как)

}

[Test]
Expand All @@ -35,18 +32,26 @@ public void CheckCurrentTsar_WithCustomEquality()
new Person("Vasili III of Russia", 28, 170, 60, null));

// Какие недостатки у такого подхода?
// При изменении класса Person придётся изменять метод AreEqual,
// т.е. если мы добавим поле в Person, то придётся добавить проверку на него в этом методе.
// При провале теста мы не получаем конкретной информации из-за чего тест не прошёл,
// т.к. метод AreEqual возвращает bool и скажет нам только Success или Failed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ага, все так

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

// Невозможно сравнить двух Person без определённых полей,
// придётся создавать различные реализации метода AreEqual.
ClassicAssert.True(AreEqual(actualTsar, expectedTsar));
}

private bool AreEqual(Person? actual, Person? expected)
{
if (actual == expected) return true;
if (actual == null || expected == null) return false;
if (actual == expected)
return true;
if (actual == null || expected == null)
return false;
return
actual.Name == expected.Name
&& actual.Age == expected.Age
&& actual.Height == expected.Height
&& actual.Weight == expected.Weight
&& AreEqual(actual.Parent, expected.Parent);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public NumberValidator(int precision, int scale = 0, bool onlyPositive = false)
if (precision <= 0)
throw new ArgumentException("precision must be a positive number");
if (scale < 0 || scale >= precision)
throw new ArgumentException("precision must be a non-negative number less or equal than precision");
throw new ArgumentException("scale must be a non-negative number less than precision");
numberRegex = new Regex(@"^([+-]?)(\d+)([.,](\d+))?$", RegexOptions.IgnoreCase);
}

Expand Down
183 changes: 160 additions & 23 deletions Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,168 @@

using NUnit.Framework;
using NUnit.Framework.Legacy;
using NUnit.Framework;
using FluentAssertions;

namespace HomeExercise.Tasks.NumberValidator;

[TestFixture]
public class NumberValidatorTests
{
[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"));
[TestCase(1, TestName = "Correct parameters")]
public void Constructor_WithCorrectParameters_NotThrows(int precision, int scale = 0)
{
var creation = () => new NumberValidator(precision, scale, true);

creation.Should()
.NotThrow<ArgumentException>();
}

[TestCase(-1, TestName = "negative precision")]
[TestCase(0, TestName = "zero precision")]
public void Constructor_WithIncorrectPrecision_Throws(int precision, int scale = 0)
{
var creation = () => new NumberValidator(precision, scale);

creation.Should()
.Throw<ArgumentException>()
.WithMessage("precision must be a positive number");
}

[TestCase(1, -1, TestName = "negative scale")]
[TestCase(1, 2, TestName = "scale greater than precision")]
[TestCase(1, 1, TestName = "scale equal to precision")]
public void Constructor_WithIncorrectScale_Throws(int precision, int scale)
{
var creation = () => new NumberValidator(precision, scale);

creation.Should()
.Throw<ArgumentException>()
.WithMessage("scale must be a non-negative number less than precision");
}

[TestCase("+11", TestName = "less numbers than precision (intPart with plus)")]
[TestCase("-1.1", TestName = "less numbers than precision (intPart and fracPart with minus)")]
[TestCase("11", TestName = "less numbers than precision (only intPart)")]
[TestCase("1.1", TestName = "less numbers than precision (intPart and fracPart)")]
[TestCase("123", TestName = "numbers equals precision (only intPart)")]
[TestCase("1.23", TestName = "numbers equals precision (intPart and fracPart)")]
public void IsValidNumber_WithCorrectPrecision_ReturnsTrue(string expectedResultValue)
{
new NumberValidator(3, 2).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase("+1", TestName = "number with plus")]
[TestCase("1", TestName = "number without sign")]
public void IsValidNumber_WithOnlyPositive_ReturnsTrue(string expectedResultValue)
{
new NumberValidator(2, 1, true).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase("-1", TestName = "number with minus")]
[TestCase("+1", TestName = "number with plus")]
[TestCase("1", TestName = "number without sign")]
public void IsValidNumber_WithNotOnlyPositive_ReturnsTrue(string expectedResultValue)
{
new NumberValidator(2, 1).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase(2, 0, true, "+1", TestName = "number with a plus")]
[TestCase(3, 1, true, "+1.2", TestName = "number with a plus and separator dot")]
[TestCase(3, 1, true, "+1,2", TestName = "number with a plus and separator comma")]
public void IsValidNumber_WithCorrectPlus_ReturnsTrue(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

что именно проверяет этот тест?
ниже аналогичный IsValidNumber_WithCorrectMinus_ReturnsTrue тоже не понятен

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То что именно плюсы и минусы корректно обрабатываются при подсчете intPart

int precision,
int scale,
bool onlyPositive,
string expectedResultValue)
{
new NumberValidator(precision, scale, onlyPositive).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase(2, 0, "-1", TestName = "number with a minus")]
[TestCase(3, 1, "-1.2", TestName = "number with a minus and separator dot")]
[TestCase(3, 1, "-1,2", TestName = "number with a minus and separator comma")]
public void IsValidNumber_WithCorrectMinus_ReturnsTrue(
int precision,
int scale,
string expectedResultValue)
{
new NumberValidator(precision, scale).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase(1, 0, "0", TestName = "one digit")]
[TestCase(3, 0, "123", TestName = "three digits")]
[TestCase(3, 1, "12.3", TestName = "three digits with one number after the dot")]
[TestCase(3, 2, "1.23", TestName = "three digits with two number after the dot")]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Писать в названии количество цифр бессмысленно. Тесты - это документация, ты начинаешь утверждать, что если число из 3х цифр, то метод вернет true. Здесь лучше что-то типа: "number of digits match precision". В общем-то у тебя везде все названо хорошо, подгляди в соседний метод.

public void IsValidNumber_WithCorrectNumberOfDigits_ReturnsTrue(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А в чем разница с IsValidNumber_WithCorrectPrecision_ReturnsTrue?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Идея была в том, чтобы в IsValidNumber_WithCorrectPrecision_ReturnsTrue проверять именно Precision без scale, а в IsValidNumber_WithCorrectNumberOfDigits_ReturnsTrue как бы комбинированная проверка

int precision,
int scale,
string expectedResultValue)
{
new NumberValidator(precision, scale).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase("0.1", TestName = "separator dot")]
[TestCase("0,1", TestName = "separator comma")]
public void IsValidNumber_WithCorrectSeparator_ReturnsTrue(string expectedResultValue)
{
new NumberValidator(2, 1).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase("0.1", TestName = "separator dot")]
[TestCase("0,1", TestName = "separator comma")]
[TestCase("1", TestName = "number")]
[TestCase("+1", TestName = "number with plus")]
[TestCase("-1", TestName = "number with minus")]
public void IsValidNumber_WithStringCorrectFormat_ReturnsTrue(string expectedResultValue)
{
new NumberValidator(2, 1).IsValidNumber(expectedResultValue).Should().BeTrue();
}

[TestCase("", TestName = "empty string")]
[TestCase(null, TestName = "null")]
public void IsValidNumber_WithNullOrEmpty_ReturnsFalse(string expectedResultValue)
{
new NumberValidator(2, 1).IsValidNumber(expectedResultValue).Should().BeFalse();
}

[TestCase(".0", TestName = "intPart is missing")]
[TestCase("0.", TestName = "fracPart part is missing")]
[TestCase("0.0.0", TestName = "more than one separator")]
[TestCase(" 1 ", TestName = "spaces on the sides")]
[TestCase("1 . 1", TestName = "spaces on the sides of the separator")]
[TestCase("1 1", TestName = "spaces between numbers")]
[TestCase("1'1", TestName = "foreign separator (apostrophe)")]
[TestCase("1`1", TestName = "foreign separator (backtick)")]
[TestCase("1~1", TestName = "foreign separator (tilde)")]
[TestCase("1/1", TestName = "foreign separator (slash)")]
[TestCase("a", TestName = "not a number")]
[TestCase("a.a", TestName = "not a number with separator dot")]
[TestCase("a,a", TestName = "not a number with separator comma")]
public void IsValidNumber_WithStringIncorrectFormat_ReturnsFalse(string expectedResultValue)
{
new NumberValidator(2, 1).IsValidNumber(expectedResultValue).Should().BeFalse();
}

[TestCase("+11", TestName = "more numbers than precision (intPart with plus)")]
[TestCase("-1.1", TestName = "more numbers than precision (intPart and fracPart with minus)")]
[TestCase("123", TestName = "more numbers than precision (only intPart)")]
[TestCase("1.23", TestName = "more numbers than precision (intPart and fracPart)")]
public void IsValidNumber_WithIncorrectPrecision_ReturnsFalse(string expectedResultValue)
{
new NumberValidator(2).IsValidNumber(expectedResultValue).Should().BeFalse();
}

[TestCase("0.12", TestName = "more digits in fracPart than scale")]
[TestCase("+0.12", TestName = "more digits in fracPart than scale with plus")]
[TestCase("-0.12", TestName = "more digits in fracPart than scale with minus")]
public void IsValidNumber_WithIncorrectScale_ReturnsFalse(string expectedResultValue)
{
new NumberValidator(2, 1).IsValidNumber(expectedResultValue).Should().BeFalse();
}

[TestCase("-1", TestName = "number with minus")]
[TestCase("-1.1", TestName = "number with minus and separator dot")]
[TestCase("-1,1", TestName = "number with minus and separator comma")]
public void IsValidNumber_WithOnlyPositive_ReturnsFalse(string expectedResultValue)
{
new NumberValidator(2, 1, true).IsValidNumber(expectedResultValue).Should().BeFalse();
}
}