-
Notifications
You must be signed in to change notification settings - Fork 281
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
Бабин Георгий #240
Open
tripples25
wants to merge
8
commits into
kontur-courses:master
Choose a base branch
from
tripples25:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Бабин Георгий #240
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
e5c6bb5
Rewrite CheckCurrentTsar on using FluentAssertions
tripples25 3deaa3c
Refactored NumberValidatorTests and added missing tests
tripples25 d100a68
Added an answer to the question
tripples25 5ec33cb
Merge number-validator-tests-refactor branch
tripples25 b0124c5
Split files in HomeExercises in separate classes
tripples25 f0d9880
Added additional tests in NumberValidatorTests
tripples25 8478ac8
Removed unnecessary constructor tests and did refactor in NumberValid…
tripples25 6cb0cc9
Changed onlyPositive argument in some TestCases in NumberValidatorTests
tripples25 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace HomeExercises.NumberValidator | ||
{ | ||
public class NumberValidator | ||
{ | ||
private readonly Regex numberRegex; | ||
private readonly bool onlyPositive; | ||
private readonly int precision; | ||
private readonly int scale; | ||
|
||
public NumberValidator(int precision, int scale = 0, bool onlyPositive = false) | ||
{ | ||
this.precision = precision; | ||
this.scale = scale; | ||
this.onlyPositive = onlyPositive; | ||
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"); | ||
numberRegex = new Regex(@"^([+-]?)(\d+)([.,](\d+))?$", RegexOptions.IgnoreCase); | ||
} | ||
|
||
public bool IsValidNumber(string value) | ||
{ | ||
// Проверяем соответствие входного значения формату N(m,k), в соответствии с правилом, | ||
// описанным в Формате описи документов, направляемых в налоговый орган в электронном виде по телекоммуникационным каналам связи: | ||
// Формат числового значения указывается в виде N(m.к), где m – максимальное количество знаков в числе, включая знак (для отрицательного числа), | ||
// целую и дробную часть числа без разделяющей десятичной точки, k – максимальное число знаков дробной части числа. | ||
// Если число знаков дробной части числа равно 0 (т.е. число целое), то формат числового значения имеет вид N(m). | ||
|
||
if (string.IsNullOrEmpty(value)) | ||
return false; | ||
|
||
var match = numberRegex.Match(value); | ||
if (!match.Success) | ||
return false; | ||
|
||
// Знак и целая часть | ||
var intPart = match.Groups[1].Value.Length + match.Groups[2].Value.Length; | ||
// Дробная часть | ||
var fracPart = match.Groups[4].Value.Length; | ||
|
||
if (intPart + fracPart > precision || fracPart > scale) | ||
return false; | ||
|
||
if (onlyPositive && match.Groups[1].Value == "-") | ||
return false; | ||
return true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System; | ||
using FluentAssertions; | ||
using NUnit.Framework; | ||
|
||
namespace HomeExercises.NumberValidator | ||
{ | ||
public class NumberValidatorTests | ||
{ | ||
[TestCase(0, 2, TestName = "precision is zero")] | ||
[TestCase(-1, 2, TestName = "precision is negative")] | ||
[TestCase(1, -1, TestName = "scale is negative")] | ||
[TestCase(1, 2, TestName = "scale is greater than precision")] | ||
[TestCase(1, 1, TestName = "scale is equals precision")] | ||
public void Constructor_Fails_OnIncorrectArguments(int precision, int scale) | ||
{ | ||
Action a = () => { new NumberValidator(precision, scale); }; | ||
a.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
[Test] | ||
public void Constructor_Success_WithOneArgument() | ||
{ | ||
Action a = () => { new NumberValidator(1); }; | ||
a.Should().NotThrow(); | ||
} | ||
|
||
[TestCase(3, 2, false, null, TestName = "value is null")] | ||
[TestCase(3, 2, false, "", TestName = "value is empty")] | ||
[TestCase(3, 2, false, " ", TestName = "value is space")] | ||
[TestCase(3, 2, false, "+1..23", TestName = "value contains two separators")] | ||
[TestCase(3, 2, false, "++0", TestName = "value contains two signs")] | ||
[TestCase(3, 2, false, "1.2a", TestName = "value contains letters")] | ||
[TestCase(3, 2, false, "+", TestName = "value only contains sign")] | ||
[TestCase(3, 2, false, "0?0", TestName = "value separated by other symbol than dot or comma")] | ||
[TestCase(3, 2, false, " 0", TestName = "value contains spaces before number")] | ||
[TestCase(3, 2, false, "0 ", TestName = "value contains spaces after number")] | ||
[TestCase(3, 2, false, "0.", TestName = "value hasn't contains numbers after separator")] | ||
[TestCase(3, 2, false, ".0", TestName = "value hasn't contains numbers before separator")] | ||
[TestCase(17, 2, false, "0.000", TestName = "value's fraction part length is greater than scale")] | ||
[TestCase(5, 2, true, "-0.00", TestName = "negative sign when onlyPositive is true")] | ||
[TestCase(3, 2, false, "+0.00", TestName = "intPart and fractPart together is greater than precision")] | ||
public void IsValidNumber_ReturnsFalse_OnIncorrectArguments(int precision, int scale, bool onlyPositive, string value) | ||
{ | ||
new NumberValidator(precision, scale, onlyPositive) | ||
.IsValidNumber(value) | ||
.Should() | ||
.BeFalse(); | ||
} | ||
|
||
[TestCase(17, 2, true, "0", TestName = "value without sign")] | ||
[TestCase(17, 2, true, "+0", TestName = "value with positive sign")] | ||
[TestCase(17, 2, false, "-0", TestName = "value with negative sign")] | ||
[TestCase(17, 2, true, "0.0", TestName = "value with period as delimiter")] | ||
[TestCase(17, 2, true, "0,0", TestName = "value with comma as delimiter")] | ||
[TestCase(17, 2, true, "+0,0", TestName = "value with sign and delimiter")] | ||
[TestCase(40, 20, true, "1234567890", TestName = "value with different numbers")] | ||
public void IsValidNumber_ReturnsTrue_OnCorrectArguments(int precision, int scale, bool onlyPositive, string value) | ||
{ | ||
new NumberValidator(precision, scale, onlyPositive) | ||
.IsValidNumber(value) | ||
.Should() | ||
.BeTrue(); | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace HomeExercises | ||
{ | ||
public class Person | ||
{ | ||
public static int IdCounter = 0; | ||
public int Age, Height, Weight; | ||
public string Name; | ||
public Person? Parent; | ||
public int Id; | ||
|
||
public Person(string name, int age, int height, int weight, Person? parent) | ||
{ | ||
Id = IdCounter++; | ||
Name = name; | ||
Age = age; | ||
Height = height; | ||
Weight = weight; | ||
Parent = parent; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace HomeExercises.TsarRegistry | ||
{ | ||
public class TsarRegistry | ||
{ | ||
public static Person GetCurrentTsar() | ||
{ | ||
return new Person("Ivan IV The Terrible", 54, 170, 70, | ||
new Person("Vasili III of Russia", 28, 170, 60, null)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using FluentAssertions; | ||
using NUnit.Framework; | ||
|
||
namespace HomeExercises.TsarRegistry | ||
{ | ||
public class TsarRegistryTests | ||
{ | ||
[Test] | ||
[Description("Проверка текущего царя")] | ||
public void GetCurrentTsar_ReturnsCorrectTsar() | ||
{ | ||
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)); | ||
|
||
actualTsar | ||
.Should() | ||
.BeEquivalentTo(expectedTsar, options => options | ||
.Excluding(memberInfo => memberInfo.SelectedMemberInfo.DeclaringType == typeof(Person) | ||
&& memberInfo.SelectedMemberInfo.Name == nameof(Person.Id))); | ||
} | ||
|
||
[Test] | ||
[Description("Альтернативное решение. Какие у него недостатки?")] | ||
/* 1. Непонятно из названия, что тест проверяет и какого результата ожидает. | ||
* 2. При использовании такого Assert, при падении теста мы узнаем лишь, что мы получили False, | ||
* без дополнительной информации об отличающихся полях и т.д. | ||
* 3. При изменении класса Person нам всегда придётся соответственно менять и локальный метод | ||
* AreEqual для класса Person. | ||
* 4. Если каким-то образом произойдёт бесконечная рекурсия внутри класса Person, то данный способ привдёт к | ||
* бесконечному проходу по нему. Проверка через FluentAssertions ограничена глубиной | ||
* в 10 вхождений и это значение кастомизируемо. | ||
* 5. При добавлении новых полей в класс Person, которые мы хотим включать в этот Equals - метод может | ||
* сильно разрастись и его читаемость сильно снизится. | ||
*/ | ||
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)); | ||
|
||
// Какие недостатки у такого подхода? | ||
Assert.True(AreEqual(actualTsar, expectedTsar)); | ||
} | ||
|
||
private bool AreEqual(Person? actual, Person? expected) | ||
{ | ||
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); | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
А если разрешены только положительные, а передаем отрицательное?