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

Заколюкин Степан #227

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
13 commits
Select commit Hold shift + click to select a range
814d450
Написал черновую версию решения задачи
StepanZakolukin Dec 11, 2024
8fc1103
Написал тесты на базовую функциональность, поправил ошибки в решении
StepanZakolukin Dec 11, 2024
83caa66
Отрефакторил код
StepanZakolukin Dec 12, 2024
4beb5c6
Добавил в реализацию обработку циклических ссылок и написал тест на э…
StepanZakolukin Dec 12, 2024
ca5ec7c
Поправил ошибку в тесте на циклические ссылки и опечатку в сериализаторе
StepanZakolukin Dec 12, 2024
cb1fcd1
Добавил сериализацию коллекций и тесты на эту функциональность
StepanZakolukin Dec 12, 2024
acf83af
Отрефакторил теты на сериализацию коллекций
StepanZakolukin Dec 13, 2024
aaffddd
Добавил сообщение в вызов исключения
StepanZakolukin Dec 15, 2024
47601c2
Поправил сериализацию коллекций и тесты
StepanZakolukin Dec 16, 2024
03b57f0
Поправил сериализацию циклических ссылок
StepanZakolukin Dec 16, 2024
ddae456
Отрефакторил метод ToString()
StepanZakolukin Dec 16, 2024
e33ba0f
Применил для вызова исключения более информативную перегрузку
StepanZakolukin Dec 16, 2024
6822458
обернул проверку на финальный тип в метод IsFinalType(Type type)
StepanZakolukin Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Person
Id = Guid
Height = 185,5
Age = 19
Parent = null
Child = null
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Person
Id = Guid
Height = 185,5
Age = 19
Parent = null
Child = null
Email = [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Int32[]
1
2
3
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
List`1
1
2
3
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Dictionary`2
KeyValuePair`2
Key = 1
Value = 1
KeyValuePair`2
Key = 2
Value = 2
KeyValuePair`2
Key = 3
Value = 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Person
Id = Guid
Name = Alex
Height = 185,5
Age = 19
Parent = null
Child = null
Email = [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Person
Id = Guid
Name = Alex
Height = 185,5
Age = 10011
Parent = null
Child = null
Email = [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Person
Id = Guid
Name = Alex
Height = 185.5
Age = 19
Parent = null
Child = null
Email = [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Person
Id = Guid
Name = Хьюберт Блейн Вольфе...
Height = 185,5
Age = 19
Parent = null
Child = null
Email = [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Person
Id = Guid
Name = Alex
Height = 185,5
Age = 19
Parent = null
Child = null
Email = [email protected]
64 changes: 64 additions & 0 deletions ObjectPrinting.Tests/ObjectPrinting.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<Using Include="NUnit.Framework"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ObjectPrinting\ObjectPrinting.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="8.0.0-alpha.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0-beta.5" />
</ItemGroup>

<ItemGroup>
<None Update="ExpectedResponses\PrintToString_FullObjectSerialization.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\Excluding_MustExcludeFieldsAndTypePropertiesFromSerialization.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\Using_AnAlternativeWayToSerializeNumbers.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\Excluding_NamePropertyIsExcluded.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\Using_OtherLocalizationOfEmailField.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\Using_NamePropertyIsTruncated.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\Using_ChangedTypeSerializationCulture.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\PrintToString_Collection_SerializedCollection.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\PrintToString_Array_SerializedArray.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ExpectedResponses\PrintToString_Dictionary_SerializedDictionary.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;

namespace ObjectPrinting.Solved.Tests
namespace ObjectPrinting.Tests
{
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public double Height { get; set; }
public int Age { get; set; }
public string Email;
public Person Parent { get; set; }
public Person Child { get; set; }
}
}
163 changes: 163 additions & 0 deletions ObjectPrinting.Tests/PrintingConfigTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
using System.Globalization;
using FluentAssertions;

namespace ObjectPrinting.Tests;

public class PrintingConfigTests
Copy link

Choose a reason for hiding this comment

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

Такое ощущение, что большинство тестов имеют очень маленький extected и его проще оставить в коде. Потому что:

  1. проще читать и расширять
  2. не может быть проблем с файлами

...
Но история с тем, что у тебя есть тесты из файлов очень крутая для функциональных тестах: их суть в том, чтобы за 1 тест проверить очень много логики на жирных данных. Такие тесты полезны, например тем, чтобы на уровне тестов давать гарантии по обратной совместимости: сгенерил вывод для оч большого обьекта, проверил его глазами и положил в файл. Этот тест начнёт падать, если какие-то данные сериализации начнут меняться (из-за обновления дотнета, кривого кода и т.п.)

Copy link
Author

Choose a reason for hiding this comment

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

Исправил. Тесты с небольшим extected вытащил в код

Copy link

Choose a reason for hiding this comment

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

Раз ты вытащил в код, кажется, можно убрать кучу ненужных полей, а содержание не поменяется. Ну и ИМХО строки через @"" и переносы строк выглядит более лаконично.

Copy link
Author

Choose a reason for hiding this comment

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

Ты имеешь ввиду убрать expected в строку с проверкой?

{
private readonly Person defaultPerson = new()
{
Name = "Alex",
Age = 19,
Email = "[email protected]",
Height = 185.5
};

[Test]
public void Excluding_MustExcludeFieldsAndTypePropertiesFromSerialization()
{
var expected = File.ReadAllText("ExpectedResponses/Excluding_MustExcludeFieldsAndTypePropertiesFromSerialization.txt");
var printer = ObjectPrinter.For<Person>()
.Excluding<string>();

var actual = printer.PrintToString(defaultPerson);

actual.Should().Be(expected);
}

[Test]
public void PrintToString_FullObjectSerialization()
{
var expected = File.ReadAllText("ExpectedResponses/PrintToString_FullObjectSerialization.txt");
var printer = ObjectPrinter.For<Person>();

var actual = printer.PrintToString(defaultPerson);

actual.Should().Be(expected);
}

[Test]
public void Using_AnAlternativeWayToSerializeNumbers()
{
var expected = File.ReadAllText("ExpectedResponses/Using_AnAlternativeWayToSerializeNumbers.txt");
var printer = ObjectPrinter.For<Person>()
.Printing<int>()
.Using(number => Convert.ToString(number, 2));

var actual = printer.PrintToString(defaultPerson);

actual.Should().Be(expected);
}

[Test]
public void Excluding_NamePropertyIsExcluded()
{
var expected = File.ReadAllText("ExpectedResponses/Excluding_NamePropertyIsExcluded.txt");
var printer = ObjectPrinter.For<Person>()
.Excluding(p => p.Name);

var actual = printer.PrintToString(defaultPerson);

actual.Should().Be(expected);
}

[Test]
public void Using_OtherLocalizationOfEmailField()
{
var expected = File.ReadAllText("ExpectedResponses/Using_OtherLocalizationOfEmailField.txt");
var printer = ObjectPrinter.For<Person>()
.Printing(p => p.Email)
.Using(email => email.ToUpper() + Environment.NewLine);

var actual = printer.PrintToString(defaultPerson);

actual.Should().Be(expected);
}

[Test]
public void Using_NamePropertyIsTruncated()
{
var person = new Person
{
Name = "Хьюберт Блейн Вольфешлегельштейнхаузенбергердорф-старший",
Height = defaultPerson.Height,
Age = defaultPerson.Age,
Email = defaultPerson.Email
};
var expected = File.ReadAllText("ExpectedResponses/Using_NamePropertyIsTruncated.txt");
var printer = ObjectPrinter.For<Person>()
.Printing(p => p.Name)
.TrimmedToLength(20);

var actual = printer.PrintToString(person);

actual.Should().Be(expected);
}

[Test]
public void Using_ChangedTypeSerializationCulture()
{
var expected = File.ReadAllText("ExpectedResponses/Using_ChangedTypeSerializationCulture.txt");
var printer = ObjectPrinter.For<Person>()
.Printing<double>()
.Using(new CultureInfo("en-US"));

var actual = printer.PrintToString(defaultPerson);

actual.Should().Be(expected);
}

[Test]
public void PrintToString_CyclicLinks_NoStackOverflowException()
Copy link

Choose a reason for hiding this comment

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

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

Т.е.

  1. Такие кейсы не будут понятны: нет исключения, нет какого-то вывода в сериализуемом файле
  2. Такой кейс не зафиксирован в тестах

Copy link
Author

Choose a reason for hiding this comment

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

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

Copy link

Choose a reason for hiding this comment

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

Чётенько

{
var parent = new Person();
var child = new Person();
parent.Child = child;
child.Parent = parent;
var printer = ObjectPrinter.For<Person>();
Action act = () => printer.PrintToString(parent);

act.Should().NotThrow<StackOverflowException>();
}

[Test]
public void PrintToString_List_SerializedList()
{
var expected = File.ReadAllText("ExpectedResponses/PrintToString_Collection_SerializedCollection.txt");
var list = new List<int> { 1, 2, 3 };

CheckSerializationOfTheCollection(expected, list);
}

[Test]
public void PrintToString_Array_SerializedArray()
{
var expected = File.ReadAllText("ExpectedResponses/PrintToString_Array_SerializedArray.txt");
var array = new[] { 1, 2, 3 };

CheckSerializationOfTheCollection(expected, array);
}

[Test]
public void PrintToString_Dictionary_SerializedDictionary()
{
var expected = File.ReadAllText("ExpectedResponses/PrintToString_Dictionary_SerializedDictionary.txt");
var dict = new Dictionary<string, int>
{
{ "1", 1 },
{ "2", 2 },
{ "3", 3 }
};

CheckSerializationOfTheCollection(expected, dict);
}

private void CheckSerializationOfTheCollection<TCollection>(string expected, TCollection collection)
Copy link

Choose a reason for hiding this comment

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

Тут не полностью выполнено требование: о перечислении всех публиных полей: у списка нет свойства Count.

Copy link
Author

Choose a reason for hiding this comment

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

Поправил логику в классе сериализатора и тесты

{
var printer = ObjectPrinter.For<TCollection>();

var actual = printer.PrintToString(collection);

actual.Should().Be(expected);
}
}
6 changes: 6 additions & 0 deletions ObjectPrinting/IPropertyPrintingConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ObjectPrinting;

public interface IPropertyPrintingConfig<TOwner, TPropType>
{
PrintingConfig<TOwner> ParentConfig { get; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ObjectPrinting.Solved
namespace ObjectPrinting
{
public static class ObjectExtensions
{
Expand Down
6 changes: 0 additions & 6 deletions ObjectPrinting/ObjectPrinting.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,4 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>
</Project>
Loading