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

Попов Захар #201

Open
wants to merge 32 commits into
base: master
Choose a base branch
from

Conversation

BlizPerfect
Copy link

@BlizPerfect BlizPerfect commented Jan 16, 2025

@masssha1308

Примеры работы программы и результаты выполнения прошлых частей задания по ссылкам:

  1. 1 часть: Попов Захар tdd#257
  2. 2 часть: Попов Захар di-updated#18

FontParser теперь возвращает FontFamily
1. Добавлена фабрика по созданию WordFilter.
2. Добавлена фабрика по созданиюCloudLayouterWorker.
3. Рефакторинг DIContainer.
1. wordsToIncludeFile - добавление слов в фильтр "скучных слов" из файла.
2. wordsToExcludeFile- исключение слов из фильтра "скучных слов" из файла.
3. normalizeMinCoefficient - минимальный коэффициент нормализации.
3. Рефакторинг WordFilter.
1. Рефакторинг CloudLayouterPainter.
2. Добавлен новый тест.
1. Рефакторинг ImageSaver.
2. Обновление тестов.
1. Рефакторинг Normalizer.
2. Обновление тестов.
1. Рефакторинг ColorParser.
2. Добавлены тесты для ColorParser.
1. Рефакторинг FontParser.
2. Добавлены тесты для FontParser.
1. Рефакторинг SizeParser.
2. Добавлены тесты для SizeParser.

[assembly: InternalsVisibleTo("TagCloud")]

Choose a reason for hiding this comment

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

А для чего? Заметила что это нужно для обращения к Value класса Result. Но ведь это поле не просто так было сделано internal :) Например, вот здесь есть проверка что при вычислении ширины и высоты не было ошибок
image
Так почему бы вместо прямого доступа к Value не воспользоваться GetValueOrThrow?

Copy link
Author

@BlizPerfect BlizPerfect Jan 20, 2025

Choose a reason for hiding this comment

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

Это только для того, что бы класс Result.cs был виден для моих проектов. Можно было перекопировать этот класс в сам проект, но я решил просто сделать его видимым.

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

Choose a reason for hiding this comment

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

Это только для того, что бы класс Result.cs был виден для моих проектов. Можно было перекопировать этот класс в сам проект, но я решил просто сделать его видимым.

Не совсем понятно, почему бы публичный класс из другого проекта не будет виден без этого атрибута?)


namespace TagCloud.Tests.CloudLayouterPaintersTest
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Проверка совместимости платформы", Justification = "<Ожидание>")]

Choose a reason for hiding this comment

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

System.Diagnostics.CodeAnalysis.SuppressMessage длинновато, давай сократим с помощью юзинга

Choose a reason for hiding this comment

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

А вообще, для чего этот атрибут здесь и что значит "ожидание"?

Copy link
Author

@BlizPerfect BlizPerfect Jan 20, 2025

Choose a reason for hiding this comment

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

Это подавление сообщения об ограниченности использования класса Bitmap:
image

Можно было сделать так:

#pragma warning disable CA1416
            var dummyImage = new Bitmap(1, 1);
#pragma warning restore CA1416

Изначально добавлял игнорирование этой ошибки в GlobalSuppressions.cs:

// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Interoperability", "CA1416:Проверка совместимости платформы", Justification = "<Ожидание>", Scope = "member", Target = "~M:TagCloud.Tests.ImageSaversTests.ImageSaverTests.SaveFile_ThrowsException_WithInvalidFormat(System.String)")]

Justification обозначает вроде как причину, почему это подавление добавлено. Студия по умолчания туда прописывает "<Ожидание>" - ожидается. что когда-то там исправят. Я понимаю, что это плохая практика и в продакшене так конечно не надо делать.

Choose a reason for hiding this comment

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

ожидается. что когда-то там исправят

Ожидается) Так может и поправим?)

namespace TagCloud.Tests.CloudLayouterPaintersTest
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Проверка совместимости платформы", Justification = "<Ожидание>")]
internal class CloudLayouterPainterTest

Choose a reason for hiding this comment

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

Кажется тут все тесты с одинаковым смыслом - невалидный параметр на входе и проверяется что выкидывается исключение с нужным текстом. Давай объедим все это дело в один тест с testcases. Тогда и setUp можно будет убрать. И еще не хватает проверки позитивных сценариев. Не только что все "как надо" ломается, а еще и что работает правильно

{
[TestFixture]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Проверка совместимости платформы", Justification = "<Ожидание>")]
internal class CircularCloudLayouterMainRequirementsTest

Choose a reason for hiding this comment

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

Давай объединим CircularCloudLayouterMainRequirementsTest и CircularCloudLayouterTest. Не вижу смысла в выделении отдельного класса для теста с exception. + смущает "MainRequirements" в названии, я бы тоже убрала (если не согласен, то опиши зачем оно)

Copy link
Author

Choose a reason for hiding this comment

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

Я согласен, что конкретно сейчас название "CircularCloudLayouterMainRequirementsTest" не котируется, но оно появилось из первой части задания, как выделение проверки основным требованиям:
image

Из работы с прошлым наставником, я лично подчерпнул, что надо не бояться создавать множество тестовых файлов. Это поможет хорошо структурировать их. И конкретно тут, мне нравится, как идейно сделано, ещё со времён первой части задания - у нас есть класс, отвечающий за основные требования к раскладке и всё остальное, куда вошла только проверка на исключение.

Copy link

@masssha1308 masssha1308 Jan 21, 2025

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.

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

Нужно исправить т.к. "основные" - понятие непонятное :) хранители знания что такое в данном контексте "основное" - только люди которые видели ТЗ к задаче. А у человека который видит этот код впервые это вызовет недоумение. Следовательно, это мешает читабельности кода

Choose a reason for hiding this comment

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

А так, да. Создавать тестовые файлы не нужно бояться если есть на то причина. Очень советую почитать 9 главу "Микросевисы" Ричардсона


namespace TagCloud.Tests.CloudLayouterTests.CircularCloudLayouterTests
{
[TestFixture]

Choose a reason for hiding this comment

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

Где-то есть TestFixture, а где-то нет. Хочется придерживаться единого стиля. А вообще, в используемой версии nunit TestFixture необязателен

var maxRectangleWidth = 70;
var minRectangleHeight = 20;
var maxRectangleHeight = 50;
var rectanglesCount = 1000;

Choose a reason for hiding this comment

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

почему именно такие значения? может быть их тоже лучше рандомайзером генерить?

Copy link
Author

@BlizPerfect BlizPerfect Jan 20, 2025

Choose a reason for hiding this comment

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

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

rectangles = tags.Select(x => x.Rectangle).ToArray();
}

[TestCase(0.7, 1000)]

Choose a reason for hiding this comment

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

Есть ли смысл выносить testCase когда он один?

}
}

private (int start, int end) GetGridIndexesInterval(

Choose a reason for hiding this comment

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

Хорошо что вынес в отдельные методы, так намного читабельнее

Directory.CreateDirectory(directoryPath);
}

[SetUp]

Choose a reason for hiding this comment

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

а точно ли нужен такой setUp? В чем преимущество перед тем чтобы вместо imageSaver в тестах писать new ImageSaver()?

namespace TagCloud.Tests
{
[TestFixture]
internal class MainTest() : BaseOptionTest("MainTest")

Choose a reason for hiding this comment

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

Неинформативное название

namespace TagCloud.Tests.NormalizersTest
{
[TestFixture]
internal class NormalizerTest

Choose a reason for hiding this comment

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

В некоторых классах в названии не tests, а test. Давай все такие места поправим на tests

namespace TagCloud.Tests.OptionsTests
{
[TestFixture]
internal class BackgroundColorTests() : BaseOptionTest("BackgroundColor")
Copy link

@masssha1308 masssha1308 Jan 18, 2025

Choose a reason for hiding this comment

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

А зачем выделять для этого теста отдельный класс, почему его нельзя поместить в MainTest? Кажется по смыслу он туда подходит. Классы стоит выделать по функциональности которую проверяем (в данном случае это тест на ProgramExecutor) поэтому на мой взгляд нет необходимости проверку фона при работе выносить в отдельный класс. Если класс получится слишком большим и будет напрашиваться разделение, можно выделить 2: негативные и позитивные сценарии

Choose a reason for hiding this comment

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

Тот же самый вопрос к классам TextColorTest, FontTest и т.д.

Copy link
Author

@BlizPerfect BlizPerfect Jan 20, 2025

Choose a reason for hiding this comment

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

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

  • Название папки - OptionsTests - тестируются аргументы командной строки, передаваемые нашей программе.
  • Название файла/Класса - FontTests - тестируются опции, относящиеся к шрифтам, которые мы передаём как аргументы для работы нашей программы.
  • Название теста - Program_WorksCorrectly_WithInvalidFont - тестируется работа программы, при передаче через командную строку некорректного аргумента, относящегося к шрифтам.

Из работы с прошлым наставником я такую логику структурирования подчерпнул.

Название "MainTest" - откровенно не лучшее, я честно говоря думал, что поменял его. Сейчас его название лучше отражает, что я имел ввиду - FullProgramExecutionTests - тесты, направленные на проверку результата полной работы программы.

{
internal static class ValidValues
{
public readonly static string[] ValidDataFileContent = new string[]

Choose a reason for hiding this comment

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

inconsistent modifiers declaration order

{ "Three", 1 },
{ "Four", 4 },
};
var values = new string[]

Choose a reason for hiding this comment

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

Кажется такое есть в ValidValues

@@ -1,14 +1,21 @@

Microsoft Visual Studio Solution File, Format Version 12.00

Choose a reason for hiding this comment

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

кажется в mr попали лишние файлы

1. Тесты с CircularCloudLayouterMainRequirementsTest добавлены в CircularCloudLayouterTest.
2. Рефакторинг CircularCloudLayouterTest.
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