Skip to content

Савицких Антон#251

Open
Xineev wants to merge 5 commits intokontur-courses:masterfrom
Xineev:master
Open

Савицких Антон#251
Xineev wants to merge 5 commits intokontur-courses:masterfrom
Xineev:master

Conversation

@Xineev
Copy link
Copy Markdown

@Xineev Xineev commented Nov 20, 2025

Copy link
Copy Markdown

@SquirrelLeonid SquirrelLeonid left a comment

Choose a reason for hiding this comment

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

В целом все гуд, но оставил несколько комментариев для правок

Comment thread ObjectPrinting/Tests/Company.cs Outdated
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Тут есть неиспользуемые зависимости

Comment thread ObjectPrinting/Tests/Node.cs Outdated
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

И тут тоже неиспользуемые зависимости

{
var result = personConfig.PrintToString(testPerson);

Assert.That(result, Contains.Substring("Person"));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Здесь оставлю комментарий, но он относится ко всем вызовам Contains.Substring в рамках тестов.

При таком сравнении строк есть проблема: если PrintingConfig начнет возвращать что-то вроде "Person abracadabra Name = John Doe", то тесты не отловят это изменение.
При таких сценариях я обычно предпочитаю формировать эталонную строку и использовать ее для сравнения.
Подозреваю, что такой способ ты выбрал, чтобы обработать случаи с разными признаками конца строки (Enviroment.NewLine).
Тут можно поступить так - эталонную строку сформировать в какой-то одной нотации (пусть, например, новая строка это \r\n), а перед сравнением сделать подмену этих символов на Environment.NewLine.

Так ты однозначно зафиксируешь формат, который ожидается на выходе

var result = nodeConfig.PrintToString(node1);

Assert.That(result, Contains.Substring("Cyclic reference detected"));
Assert.DoesNotThrow(() => nodeConfig.PrintToString(node1));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Я бы сказал, что эту проверку можно вообще опустить. Действие выше уже предполагает, что код не должен падать.
Либо эта проверка должна идти до получения result

}

[TestFixture]
public class TypeExcludeTests
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Комментарий относится к этому классу и другим подклассам с тестами.
Наличие нескольких классов в одном файле усложняет навигацию (в обозревателе будет один ObjectPrinterAcceptanceTests). Иногда такая структура бывает уместна, например в сценариях, когда у класса есть какое-то внутреннее представление, которое не несет пользы для внешнего кода.

Кроме того, хорошо просматривается дублирование кода в телах методов Setup. Это дело можно вынести в общий класс, через наследование

Comment thread ObjectPrinting/PrintingConfig.cs Outdated
return "null" + Environment.NewLine;

var finalTypes = new[]
// �������� �� ����������� ������
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Тут что-то с кодировкой у тебя случилось. Стоит поправить и использовать одну и ту же во всех файлах

Comment thread ObjectPrinting/PrintingConfig.cs Outdated
return finalTypes.Contains(obj.GetType());
}

private string HandleFinalType(object obj)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Стоит переименовать obj в finalTypeObj. Это даст еще больше ясности в код

Comment thread ObjectPrinting/PrintingConfig.cs Outdated

private string HandleFinalType(object obj)
{
var type = obj.GetType();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Так стоит сделать, потому что определение типа в рантайме может дорого стоить.
Есть альтернативный способ через оператор typeof. Он определяет типы на этапе компиляции, но здесь, если не ошибаюсь, его не получится применить в полной мере (хотя в определенных местах можно и заиспользовать)

Comment thread ObjectPrinting/PrintingConfig.cs Outdated
private string HandleCollection(IEnumerable collection, int nestingLevel)
{
var sb = new StringBuilder();
var identation = new string('\t', nestingLevel + 1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Тут очепятка кажется

}
else
{
sb.AppendLine("Collection");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Не хочешь попобовать уточнить Collection до List или Array. Может даже до List<ИмяТипа> и Array[ИмяТипа].

В целом, наверное, нам не важно какая именно из двух эта коллекция. Но в тоже время мы и словарь можем рассматривать как коллекцию из пар ключ-значение, но все таки различаем его как отдельный тип.

@SquirrelLeonid
Copy link
Copy Markdown

Ага, стало лучше, но отмечу еще два момента.
Первый. Кодировка у PrintingConfig.cs все еще страдает. Попробуй сделать вот что:

  1. Сохрани код в простом текстовом файле (убедись, что кодировка в нем UTF-8)
  2. Удали PrintingConfig.cs и сделай коммит.
  3. Создай новый PrintingConfig и вставь в него сохраненный код. Вообще, самое надежное здесь - это перебить код руками, но это дольше.

Это рутинная работа, но такие проблемы не должны появляться в коде. Хорошо, что IDE может определить подходящую кодировку, но в худшем случае файл может стать нечитаемым, если знание о кодировке утеряно.
У тебя нет предположений, как другая кодировка могла попасть в файл?

Второй. Тесты стали чище, после того как ты унес SetUp и TearDown в базовый класс. Гуд. Но у меня все еще вызывает сомнения использование подклассов для разделения тестов.

Вложенные классы стоит использовать тогда, когда внешний к ним класс зависит от их функциональности. Или если эти классы инкапсулируют какую-то часть логики, которая актуальна только для внешнего класса. Как пример могу привести реализацию какой-нибудь древесной структуры. Снаружи у тебя будет доступен класс Tree, а внутри себя он инкапсулирует часть логики в классе TreeNode.

public class Tree
{
   // Какой-то код, с логикой дерева, публичные методы

   private class TreeNode
   {
      // Код с логикой обработки конкретного узла дерева. 
      // Или просто внутреннее представление узла, которым пользуется класс выше, но наружу это пользы не несет
   }
}

В тестах же у тебя такой зависимости нет. Каждый из классов самостоятелен в том смысле, что может запускать размещенные в нем тесты и не полагается на соседние. К чему я веду - такое разделение на подклассы в тестах выглядит, на мой взгляд, искусственно. Да, в обозревателе тестов их смотреть удобно, но в обозревателе решения мы по прежнему будем видеть один класс ObjectPrinterAcceptanceTests.cs.

Я не буду требовать этого изменения и оставлю решение за тобой, но все же предложу два варианта, как на мой взгляд было бы лучше:

  1. Вложенные классы с тестами унести в отдельные файлы. Эти файлы структурировать в папку ObjectPrinterTests (например).
  2. Убрать все вложенные классы и разместить все тесты в ObjectPrinterAcceptanceTests. На первый взгляд может показаться, что упадет читаемость, но по сути то, что тест проверяет, заложено в его названии.

@SquirrelLeonid
Copy link
Copy Markdown

Гуд. Полное решение засчитываю

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants