From 7b477f044230af2eacdff1b1cb9a8c44db58e11e Mon Sep 17 00:00:00 2001 From: Emi1337-ops Date: Thu, 12 Dec 2024 00:12:05 +0500 Subject: [PATCH 1/4] Add Homework Task Solution --- ObjectPrinting/Extensions/ObjectExtensions.cs | 16 ++ .../PropertyPrintingConfigExtensions.cs | 18 ++ ObjectPrinting/ObjectPrinter.cs | 11 +- ObjectPrinting/ObjectPrinting.csproj | 9 + ObjectPrinting/PrintingConfig.cs | 226 ++++++++++++++++-- ObjectPrinting/PropertyPrintingConfig.cs | 46 ++++ ObjectPrinting/Solved/ObjectExtensions.cs | 10 - ObjectPrinting/Solved/ObjectPrinter.cs | 10 - ObjectPrinting/Solved/PrintingConfig.cs | 62 ----- .../Solved/PropertyPrintingConfig.cs | 32 --- .../PropertyPrintingConfigExtensions.cs | 18 -- .../Tests/ObjectPrinterAcceptanceTests.cs | 40 ---- ObjectPrinting/Solved/Tests/Person.cs | 12 - .../Tests/ObjectPrinterAcceptanceTests.cs | 27 --- ObjectPrinting/Tests/ObjectPrinterTests.cs | 214 +++++++++++++++++ ObjectPrinting/Tests/Person.cs | 26 +- ...ernativePropertySerialization.verified.txt | 9 + ..._AlternativeTypeSerialization.verified.txt | 9 + ...intToString_CircularReference.verified.txt | 9 + ...ng_Correct_WhenCallAllMethods.verified.txt | 7 + ...PrintToString_ExcludeProperty.verified.txt | 8 + ...sts.PrintToString_ExcludeType.verified.txt | 8 + ....PrintToString_SerializeArray.verified.txt | 19 ++ ...tToString_SerializeDictionary.verified.txt | 23 ++ ...s.PrintToString_SerializeList.verified.txt | 19 ++ ...oString_SetCultureForProperty.verified.txt | 9 + ...intToString_SetCultureForType.verified.txt | 9 + ...interTests.PrintToString_Trim.verified.txt | 9 + .../FluentMapping.Tests.csproj | 1 + Samples/FluentMapper/FluentMapping.csproj | 7 + Samples/Spectacle/Spectacle.csproj | 7 + 31 files changed, 679 insertions(+), 251 deletions(-) create mode 100644 ObjectPrinting/Extensions/ObjectExtensions.cs create mode 100644 ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs create mode 100644 ObjectPrinting/PropertyPrintingConfig.cs delete mode 100644 ObjectPrinting/Solved/ObjectExtensions.cs delete mode 100644 ObjectPrinting/Solved/ObjectPrinter.cs delete mode 100644 ObjectPrinting/Solved/PrintingConfig.cs delete mode 100644 ObjectPrinting/Solved/PropertyPrintingConfig.cs delete mode 100644 ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs delete mode 100644 ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs delete mode 100644 ObjectPrinting/Solved/Tests/Person.cs delete mode 100644 ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs create mode 100644 ObjectPrinting/Tests/ObjectPrinterTests.cs create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt create mode 100644 ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt diff --git a/ObjectPrinting/Extensions/ObjectExtensions.cs b/ObjectPrinting/Extensions/ObjectExtensions.cs new file mode 100644 index 00000000..cefb2649 --- /dev/null +++ b/ObjectPrinting/Extensions/ObjectExtensions.cs @@ -0,0 +1,16 @@ +using System; + +namespace ObjectPrinting.Extensions; + +public static class ObjectExtensions +{ + public static string PrintToString(this T obj) + { + return ObjectPrinter.For().PrintToString(obj); + } + + public static string PrintToString(this T obj, Func, PrintingConfig> config) + { + return config(ObjectPrinter.For()).PrintToString(obj); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs b/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs new file mode 100644 index 00000000..4627b89c --- /dev/null +++ b/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs @@ -0,0 +1,18 @@ +using System; + +namespace ObjectPrinting.Extensions; + +public static class PropertyPrintingConfigExtensions +{ + public static PrintingConfig TrimmedToLength( + this PropertyPrintingConfig propConfig, + int maxLen) + { + if (string.IsNullOrEmpty(propConfig.PropertyName)) + throw new ArgumentException("The name of the property is not specified."); + + propConfig.ParentConfig.AddLengthProperty(propConfig.PropertyName, maxLen); + + return propConfig.ParentConfig; + } +} \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinter.cs b/ObjectPrinting/ObjectPrinter.cs index 3c7867c3..caa93e56 100644 --- a/ObjectPrinting/ObjectPrinter.cs +++ b/ObjectPrinting/ObjectPrinter.cs @@ -1,10 +1,9 @@ -namespace ObjectPrinting +namespace ObjectPrinting; + +public static class ObjectPrinter { - public class ObjectPrinter + public static PrintingConfig For() { - public static PrintingConfig For() - { - return new PrintingConfig(); - } + return new PrintingConfig(); } } \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinting.csproj b/ObjectPrinting/ObjectPrinting.csproj index c5db392f..ae2365fd 100644 --- a/ObjectPrinting/ObjectPrinting.csproj +++ b/ObjectPrinting/ObjectPrinting.csproj @@ -5,8 +5,17 @@ + + + + + + + $([System.String]::Copy('%(FileName)').Split('.')[0].Split('(')[0]) + %(ParentFile).cs + diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index a9e08211..0faa397e 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -1,41 +1,215 @@ using System; -using System.Linq; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq.Expressions; +using System.Reflection; using System.Text; -namespace ObjectPrinting +namespace ObjectPrinting; + +public class PrintingConfig { - public class PrintingConfig + private readonly HashSet finalTypes = + [ + typeof(string), typeof(DateTime), typeof(TimeSpan), typeof(Guid) + ]; + private readonly HashSet excludedTypes = []; + private readonly Dictionary> typeSerializationMethods = []; + private readonly Dictionary typeCultures = []; + private readonly Dictionary propertyCultures = []; + private readonly Dictionary> propertySerializationMethods = []; + private readonly HashSet excludedProperties = []; + private readonly HashSet processedObjects = []; + private readonly Dictionary propertyLengths = new(); + + public PropertyPrintingConfig Printing() + { + return new PropertyPrintingConfig(this); + } + + public PropertyPrintingConfig Printing(Expression> memberSelector) + { + var propertyName = GetPropertyName(memberSelector); + + return new PropertyPrintingConfig(this, propertyName); + } + + public string PrintToString(TOwner obj) + { + return PrintToString(obj, 0); + } + + private string PrintToString(object? obj, int nestingLevel) { - public string PrintToString(TOwner obj) + if (obj == null) { - return PrintToString(obj, 0); + return "null" + Environment.NewLine; } - private string PrintToString(object obj, int nestingLevel) + if (processedObjects.Contains(obj)) { - //TODO apply configurations - if (obj == null) - return "null" + Environment.NewLine; + return "Circular Reference" + Environment.NewLine; + } - var finalTypes = new[] - { - typeof(int), typeof(double), typeof(float), typeof(string), - typeof(DateTime), typeof(TimeSpan) - }; - if (finalTypes.Contains(obj.GetType())) - return obj + Environment.NewLine; - - var identation = new string('\t', nestingLevel + 1); - var sb = new StringBuilder(); - var type = obj.GetType(); - sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) + if (TrySerializeFinalType(obj, out var serializedFinalType)) + { + return serializedFinalType!; + } + + if (TrySerializeCollection(obj, nestingLevel, out var serializedCollection)) + { + return serializedCollection!; + } + + return SerializeComplexType(obj, nestingLevel); + } + + public PrintingConfig Excluding() + { + excludedTypes.Add(typeof(TPropType)); + return this; + } + + public PrintingConfig Excluding(Expression> memberSelector) + { + var propertyName = GetPropertyName(memberSelector); + excludedProperties.Add(propertyName); + return this; + } + + public void SpecifyTheCulture(CultureInfo culture) + { + typeCultures[typeof(TType)] = culture; + } + + public void SpecifyTheCulture(CultureInfo culture, string propertyName) + { + propertyCultures[propertyName] = culture; + } + + public void AddSerializationMethod(Func serializationMethod) + { + typeSerializationMethods[typeof(TType)] = obj => serializationMethod((TType)obj); + } + + public void AddSerializationMethod(Func serializationMethod, string propertyName) + { + propertySerializationMethods[propertyName] = obj => serializationMethod((TType)obj); + } + + public void AddLengthProperty(string propertyName, int trimLength) + { + propertyLengths[propertyName] = trimLength; + } + + private bool TrySerializeFinalType(object obj, out string? serializedFinalType) + { + var type = obj.GetType(); + + if (!finalTypes.Contains(type) && !type.IsPrimitive) + { + serializedFinalType = null; + return false; + } + + serializedFinalType = obj switch + { + IFormattable format when typeCultures.TryGetValue(type, out var formatProvider) => + format.ToString(null, formatProvider), + IFormattable format => + format.ToString(null, CultureInfo.InvariantCulture), + string str => str, + _ => Convert.ToString(obj) + }; + + serializedFinalType += Environment.NewLine; + + return true; + } + + private bool TrySerializeCollection(object obj, int nestingLevel, out string? serializedCollection) + { + if (obj is not IEnumerable collection) + { + serializedCollection = null; + return false; + } + + var collectionOnString = new StringBuilder(); + var indentation = new string('\t', nestingLevel + 1); + var type = obj.GetType(); + + collectionOnString.AppendLine($"{type.Name}:"); + + foreach (var item in collection) + { + collectionOnString.Append(indentation + PrintToString(item, nestingLevel + 1)); + } + + serializedCollection = collectionOnString.ToString(); + return true; + } + + private string SerializeComplexType(object obj, int nestingLevel) + { + processedObjects.Add(obj); + var serializedString = new StringBuilder(); + var indentation = new string('\t', nestingLevel + 1); + var type = obj.GetType(); + + serializedString.AppendLine(type.Name); + + foreach (var property in type.GetProperties()) + { + if (excludedTypes.Contains(property.PropertyType) || excludedProperties.Contains(property.Name)) { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); + continue; } - return sb.ToString(); + + var serializedProperty = SerializeProperty(property, obj, nestingLevel + 1); + serializedString.Append(indentation + property.Name + " = " + serializedProperty); + } + + return serializedString.ToString(); + } + + private string SerializeProperty(PropertyInfo property, object obj, int nestingLevel) + { + var propertyValue = property.GetValue(obj); + + if (typeSerializationMethods.TryGetValue(property.PropertyType, out var serializationType)) + { + return serializationType(propertyValue!) + Environment.NewLine; + } + + if (propertySerializationMethods.TryGetValue(property.Name, out var serializationProperty)) + { + return serializationProperty(propertyValue!) + Environment.NewLine; + } + + if (propertyLengths.TryGetValue(property.Name, out var length)) + { + var stringPropertyValue = Convert.ToString(propertyValue)!; + + return stringPropertyValue[..length] + Environment.NewLine; + } + + if (propertyCultures.TryGetValue(property.Name, out var formatProvider) && propertyValue is IFormattable format) + { + return format.ToString(null, formatProvider) + Environment.NewLine; + } + + return PrintToString(propertyValue, nestingLevel); + } + + private static string GetPropertyName(Expression> property) + { + if (property.Body is MemberExpression member) + { + return member.Member.Name; } + + throw new ArgumentException("Expression is not property."); } } \ No newline at end of file diff --git a/ObjectPrinting/PropertyPrintingConfig.cs b/ObjectPrinting/PropertyPrintingConfig.cs new file mode 100644 index 00000000..4f1fc555 --- /dev/null +++ b/ObjectPrinting/PropertyPrintingConfig.cs @@ -0,0 +1,46 @@ +using System; +using System.Globalization; + +namespace ObjectPrinting; + +public class PropertyPrintingConfig +{ + private readonly PrintingConfig printingConfig; + protected internal readonly string? PropertyName; + + public PropertyPrintingConfig(PrintingConfig printingConfig, string? propertyName = null) + { + this.printingConfig = printingConfig; + PropertyName = propertyName; + } + + public PrintingConfig Using(Func print) + { + if (string.IsNullOrEmpty(PropertyName)) + { + printingConfig.AddSerializationMethod(print); + } + else + { + printingConfig.AddSerializationMethod(print, PropertyName); + } + + return ParentConfig; + } + + public PrintingConfig Using(CultureInfo culture) + { + if (string.IsNullOrEmpty(PropertyName)) + { + printingConfig.SpecifyTheCulture(culture); + } + else + { + printingConfig.SpecifyTheCulture(culture, PropertyName); + } + + return ParentConfig; + } + + public PrintingConfig ParentConfig => printingConfig; +} \ No newline at end of file diff --git a/ObjectPrinting/Solved/ObjectExtensions.cs b/ObjectPrinting/Solved/ObjectExtensions.cs deleted file mode 100644 index b0c94553..00000000 --- a/ObjectPrinting/Solved/ObjectExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ObjectPrinting.Solved -{ - public static class ObjectExtensions - { - public static string PrintToString(this T obj) - { - return ObjectPrinter.For().PrintToString(obj); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/ObjectPrinter.cs b/ObjectPrinting/Solved/ObjectPrinter.cs deleted file mode 100644 index 540ee769..00000000 --- a/ObjectPrinting/Solved/ObjectPrinter.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ObjectPrinting.Solved -{ - public class ObjectPrinter - { - public static PrintingConfig For() - { - return new PrintingConfig(); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PrintingConfig.cs b/ObjectPrinting/Solved/PrintingConfig.cs deleted file mode 100644 index 0ec5aeb2..00000000 --- a/ObjectPrinting/Solved/PrintingConfig.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace ObjectPrinting.Solved -{ - public class PrintingConfig - { - public PropertyPrintingConfig Printing() - { - return new PropertyPrintingConfig(this); - } - - public PropertyPrintingConfig Printing(Expression> memberSelector) - { - return new PropertyPrintingConfig(this); - } - - public PrintingConfig Excluding(Expression> memberSelector) - { - return this; - } - - internal PrintingConfig Excluding() - { - return this; - } - - public string PrintToString(TOwner obj) - { - return PrintToString(obj, 0); - } - - private string PrintToString(object obj, int nestingLevel) - { - //TODO apply configurations - if (obj == null) - return "null" + Environment.NewLine; - - var finalTypes = new[] - { - typeof(int), typeof(double), typeof(float), typeof(string), - typeof(DateTime), typeof(TimeSpan) - }; - if (finalTypes.Contains(obj.GetType())) - return obj + Environment.NewLine; - - var identation = new string('\t', nestingLevel + 1); - var sb = new StringBuilder(); - var type = obj.GetType(); - sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) - { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); - } - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PropertyPrintingConfig.cs b/ObjectPrinting/Solved/PropertyPrintingConfig.cs deleted file mode 100644 index a509697d..00000000 --- a/ObjectPrinting/Solved/PropertyPrintingConfig.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Globalization; - -namespace ObjectPrinting.Solved -{ - public class PropertyPrintingConfig : IPropertyPrintingConfig - { - private readonly PrintingConfig printingConfig; - - public PropertyPrintingConfig(PrintingConfig printingConfig) - { - this.printingConfig = printingConfig; - } - - public PrintingConfig Using(Func print) - { - return printingConfig; - } - - public PrintingConfig Using(CultureInfo culture) - { - return printingConfig; - } - - PrintingConfig IPropertyPrintingConfig.ParentConfig => printingConfig; - } - - public interface IPropertyPrintingConfig - { - PrintingConfig ParentConfig { get; } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs b/ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs deleted file mode 100644 index dd392239..00000000 --- a/ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace ObjectPrinting.Solved -{ - public static class PropertyPrintingConfigExtensions - { - public static string PrintToString(this T obj, Func, PrintingConfig> config) - { - return config(ObjectPrinter.For()).PrintToString(obj); - } - - public static PrintingConfig TrimmedToLength(this PropertyPrintingConfig propConfig, int maxLen) - { - return ((IPropertyPrintingConfig)propConfig).ParentConfig; - } - - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs b/ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs deleted file mode 100644 index ac52d5ee..00000000 --- a/ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Globalization; -using NUnit.Framework; - -namespace ObjectPrinting.Solved.Tests -{ - [TestFixture] - public class ObjectPrinterAcceptanceTests - { - [Test] - public void Demo() - { - var person = new Person { Name = "Alex", Age = 19 }; - - var printer = ObjectPrinter.For() - //1. Исключить из сериализации свойства определенного типа - .Excluding() - //2. Указать альтернативный способ сериализации для определенного типа - .Printing().Using(i => i.ToString("X")) - //3. Для числовых типов указать культуру - .Printing().Using(CultureInfo.InvariantCulture) - //4. Настроить сериализацию конкретного свойства - //5. Настроить обрезание строковых свойств (метод должен быть виден только для строковых свойств) - .Printing(p => p.Name).TrimmedToLength(10) - //6. Исключить из сериализации конкретного свойства - .Excluding(p => p.Age); - - string s1 = printer.PrintToString(person); - - //7. Синтаксический сахар в виде метода расширения, сериализующего по-умолчанию - string s2 = person.PrintToString(); - - //8. ...с конфигурированием - string s3 = person.PrintToString(s => s.Excluding(p => p.Age)); - Console.WriteLine(s1); - Console.WriteLine(s2); - Console.WriteLine(s3); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/Tests/Person.cs b/ObjectPrinting/Solved/Tests/Person.cs deleted file mode 100644 index 858ebbf8..00000000 --- a/ObjectPrinting/Solved/Tests/Person.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace ObjectPrinting.Solved.Tests -{ - public class Person - { - public Guid Id { get; set; } - public string Name { get; set; } - public double Height { get; set; } - public int Age { get; set; } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs deleted file mode 100644 index 4c8b2445..00000000 --- a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -using NUnit.Framework; - -namespace ObjectPrinting.Tests -{ - [TestFixture] - public class ObjectPrinterAcceptanceTests - { - [Test] - public void Demo() - { - var person = new Person { Name = "Alex", Age = 19 }; - - var printer = ObjectPrinter.For(); - //1. Исключить из сериализации свойства определенного типа - //2. Указать альтернативный способ сериализации для определенного типа - //3. Для числовых типов указать культуру - //4. Настроить сериализацию конкретного свойства - //5. Настроить обрезание строковых свойств (метод должен быть виден только для строковых свойств) - //6. Исключить из сериализации конкретного свойства - - string s1 = printer.PrintToString(person); - - //7. Синтаксический сахар в виде метода расширения, сериализующего по-умолчанию - //8. ...с конфигурированием - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterTests.cs b/ObjectPrinting/Tests/ObjectPrinterTests.cs new file mode 100644 index 00000000..8726516e --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterTests.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using NUnit.Framework; +using ObjectPrinting.Extensions; +using VerifyNUnit; +using VerifyTests; + +namespace ObjectPrinting.Tests; + +[TestFixture] +public class ObjectPrinterTests +{ + private static readonly VerifySettings Settings = new(); + private Person person; + + [SetUp] + public void Setup() + { + Settings.UseDirectory("snapshots"); + person = new Person + { + Name = "Bob", + Age = 20, + Height = 200, + Weight = 100, + Birthday = new DateTime(2000, 10, 10), + IsStudent = true + }; + } + + [Test] + public Task PrintToString_ExcludeType() + { + var actual = ObjectPrinter.For() + .Excluding() + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_Correct_WhenCallAllMethods() + { + person.Height = 200.2; + person.Weight = 100.11; + var russianCulture = new CultureInfo("ru-RU"); + var actual = ObjectPrinter.For() + .Excluding() + .Excluding(p => p.Id) + .Printing() + .Using(_ => "date") + .Printing() + .Using(russianCulture) + .Printing(p => p.Name) + .TrimmedToLength(2) + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_AlternativeTypeSerialization() + { + var actual = ObjectPrinter.For() + .Printing() + .Using(_ => "date") + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SetCultureForType() + { + person.Height = 200.2; + person.Weight = 100.11; + var russianCulture = new CultureInfo("ru-RU"); + + var actual = ObjectPrinter.For() + .Printing() + .Using(russianCulture) + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SetCultureForProperty() + { + person.Height = 200.2; + person.Weight = 100.11; + var russianCulture = new CultureInfo("ru-RU"); + + var actual = ObjectPrinter.For() + .Printing(p => p.Height) + .Using(russianCulture) + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_AlternativePropertySerialization() + { + var actual = ObjectPrinter.For() + .Printing(p => p.Name) + .Using(_ => "NoName") + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_Trim() + { + var actual = ObjectPrinter.For() + .Printing(p => p.Name) + .TrimmedToLength(2) + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_ExcludeProperty() + { + var actual = ObjectPrinter.For() + .Excluding(p => p.Id) + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_CircularReference() + { + person.Father = person; + + var actual = ObjectPrinter.For().PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SerializeArray() + { + var persons = new[] + { + person, + new() + { + Name = "Bread", + Age = 22, + Height = 222, + Weight = 111, + Birthday = new DateTime(2001, 11, 11), + IsStudent = false + } + }; + + var actual = ObjectPrinter.For().PrintToString(persons); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SerializeList() + { + var persons = new List + { + person, + new() + { + Name = "Bread", + Age = 22, + Height = 222, + Weight = 111, + Birthday = new DateTime(2001, 11, 11), + IsStudent = false + } + }; + + var actual = ObjectPrinter.For>().PrintToString(persons); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SerializeDictionary() + { + var persons = new Dictionary + { + { person, "first" }, + { + new() + { + Name = "Bread", + Age = 22, + Height = 222, + Weight = 111, + Birthday = new DateTime(2001, 11, 11), + IsStudent = false + }, + "second" + } + }; + + var actual = ObjectPrinter.For>().PrintToString(persons); + + return Verifier.Verify(actual, Settings); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/Person.cs b/ObjectPrinting/Tests/Person.cs index f9555955..da8b234b 100644 --- a/ObjectPrinting/Tests/Person.cs +++ b/ObjectPrinting/Tests/Person.cs @@ -1,12 +1,22 @@ using System; -namespace ObjectPrinting.Tests +namespace ObjectPrinting.Tests; + +public class Person { - public class Person - { - public Guid Id { get; set; } - public string Name { get; set; } - public double Height { get; set; } - public int Age { get; set; } - } + public Guid Id { get; set; } + + public string Name { get; set; } + + public double Height { get; set; } + + public double Weight { get; set; } + + public int Age { get; set; } + + public DateTime Birthday { get; set; } + + public bool IsStudent { get; set; } + + public Person? Father { get; set; } } \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt new file mode 100644 index 00000000..eca95843 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = NoName + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt new file mode 100644 index 00000000..f0a7c193 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = date + IsStudent = True + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt new file mode 100644 index 00000000..5b7723d5 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = Circular Reference diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt new file mode 100644 index 00000000..a3d4259c --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt @@ -0,0 +1,7 @@ +Person + Name = Bo + Height = 200,2 + Weight = 100,11 + Age = 20 + Birthday = date + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt new file mode 100644 index 00000000..8226d328 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt @@ -0,0 +1,8 @@ +Person + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt new file mode 100644 index 00000000..94d0a158 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt @@ -0,0 +1,8 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt new file mode 100644 index 00000000..3feff897 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt @@ -0,0 +1,19 @@ +Person[]: + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bread + Height = 222 + Weight = 111 + Age = 22 + Birthday = 11/11/2001 00:00:00 + IsStudent = False + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt new file mode 100644 index 00000000..9797b02d --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt @@ -0,0 +1,23 @@ +Dictionary`2: + KeyValuePair`2 + Key = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null + Value = first + KeyValuePair`2 + Key = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bread + Height = 222 + Weight = 111 + Age = 22 + Birthday = 11/11/2001 00:00:00 + IsStudent = False + Father = null + Value = second diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt new file mode 100644 index 00000000..498a0de8 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt @@ -0,0 +1,19 @@ +List`1: + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bread + Height = 222 + Weight = 111 + Age = 22 + Birthday = 11/11/2001 00:00:00 + IsStudent = False + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt new file mode 100644 index 00000000..9091c50c --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200,2 + Weight = 100.11 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt new file mode 100644 index 00000000..878e54b1 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200,2 + Weight = 100,11 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt new file mode 100644 index 00000000..0a320f44 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bo + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj b/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj index 3828c566..7a537ca7 100644 --- a/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj +++ b/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj @@ -6,6 +6,7 @@ + diff --git a/Samples/FluentMapper/FluentMapping.csproj b/Samples/FluentMapper/FluentMapping.csproj index fa71b7ae..e112e832 100644 --- a/Samples/FluentMapper/FluentMapping.csproj +++ b/Samples/FluentMapper/FluentMapping.csproj @@ -6,4 +6,11 @@ enable + + + + + + + diff --git a/Samples/Spectacle/Spectacle.csproj b/Samples/Spectacle/Spectacle.csproj index fa71b7ae..e112e832 100644 --- a/Samples/Spectacle/Spectacle.csproj +++ b/Samples/Spectacle/Spectacle.csproj @@ -6,4 +6,11 @@ enable + + + + + + + From 6df1ebc33cc5c277469f5f82d8302536d64ce799 Mon Sep 17 00:00:00 2001 From: Emi1337-ops Date: Thu, 12 Dec 2024 18:54:46 +0500 Subject: [PATCH 2/4] Refactor Homewark Solution --- ObjectPrinting/Extensions/ObjectExtensions.cs | 16 -- ObjectPrinting/ObjectPrinting.csproj | 11 - ObjectPrinting/ObjectSerializer.cs | 189 +++++++++++++++ ObjectPrinting/PrintingConfig.cs | 186 ++------------- ObjectPrinting/PrintingConfigStorage.cs | 13 ++ ObjectPrinting/ReflectionHelper.cs | 12 + Samples/Spectacle/Program.cs | 24 +- Test/Test.csproj | 24 ++ .../Tests/ObjectPrinterTests.cs | 0 {ObjectPrinting => Test}/Tests/Person.cs | 0 ...ernativePropertySerialization.verified.txt | 0 ..._AlternativeTypeSerialization.verified.txt | 0 ...intToString_CircularReference.verified.txt | 0 ...ng_Correct_WhenCallAllMethods.verified.txt | 0 ...PrintToString_ExcludeProperty.verified.txt | 0 ...sts.PrintToString_ExcludeType.verified.txt | 0 ....PrintToString_SerializeArray.verified.txt | 0 ...tToString_SerializeDictionary.verified.txt | 0 ...s.PrintToString_SerializeList.verified.txt | 0 ...oString_SetCultureForProperty.verified.txt | 0 ...intToString_SetCultureForType.verified.txt | 0 ...interTests.PrintToString_Trim.verified.txt | 0 Tests/ObjectPrinterTests.cs | 219 ++++++++++++++++++ Tests/Person.cs | 27 +++ ...ernativePropertySerialization.verified.txt | 9 + ..._AlternativeTypeSerialization.verified.txt | 9 + ...intToString_CircularReference.verified.txt | 9 + ...ng_Correct_WhenCallAllMethods.verified.txt | 7 + ...PrintToString_ExcludeProperty.verified.txt | 8 + ...sts.PrintToString_ExcludeType.verified.txt | 8 + ....PrintToString_SerializeArray.verified.txt | 19 ++ ...tToString_SerializeDictionary.verified.txt | 23 ++ ...s.PrintToString_SerializeList.verified.txt | 19 ++ ...oString_SetCultureForProperty.verified.txt | 9 + ...intToString_SetCultureForType.verified.txt | 9 + ...interTests.PrintToString_Trim.verified.txt | 9 + ...g_Correct_WhenCallAllMethods.verified.txt" | 9 + Tests/Tests.csproj | 40 ++++ fluent-api.sln | 21 +- 39 files changed, 716 insertions(+), 213 deletions(-) delete mode 100644 ObjectPrinting/Extensions/ObjectExtensions.cs create mode 100644 ObjectPrinting/ObjectSerializer.cs create mode 100644 ObjectPrinting/PrintingConfigStorage.cs create mode 100644 ObjectPrinting/ReflectionHelper.cs create mode 100644 Test/Test.csproj rename {ObjectPrinting => Test}/Tests/ObjectPrinterTests.cs (100%) rename {ObjectPrinting => Test}/Tests/Person.cs (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt (100%) rename {ObjectPrinting => Test}/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt (100%) create mode 100644 Tests/ObjectPrinterTests.cs create mode 100644 Tests/Person.cs create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt create mode 100644 "Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" create mode 100644 Tests/Tests.csproj diff --git a/ObjectPrinting/Extensions/ObjectExtensions.cs b/ObjectPrinting/Extensions/ObjectExtensions.cs deleted file mode 100644 index cefb2649..00000000 --- a/ObjectPrinting/Extensions/ObjectExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace ObjectPrinting.Extensions; - -public static class ObjectExtensions -{ - public static string PrintToString(this T obj) - { - return ObjectPrinter.For().PrintToString(obj); - } - - public static string PrintToString(this T obj, Func, PrintingConfig> config) - { - return config(ObjectPrinter.For()).PrintToString(obj); - } -} \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinting.csproj b/ObjectPrinting/ObjectPrinting.csproj index ae2365fd..b3a6f3b5 100644 --- a/ObjectPrinting/ObjectPrinting.csproj +++ b/ObjectPrinting/ObjectPrinting.csproj @@ -5,17 +5,6 @@ - - - - - - - - - $([System.String]::Copy('%(FileName)').Split('.')[0].Split('(')[0]) - %(ParentFile).cs - diff --git a/ObjectPrinting/ObjectSerializer.cs b/ObjectPrinting/ObjectSerializer.cs new file mode 100644 index 00000000..1c08dc04 --- /dev/null +++ b/ObjectPrinting/ObjectSerializer.cs @@ -0,0 +1,189 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Text; +using System; +using System.Collections; + +public class ObjectSerializer +{ + private readonly PrintingConfigStorage _config; + private readonly HashSet _processedObjects = new(); + private const char tab = '\t'; + + public ObjectSerializer(PrintingConfigStorage config) + { + _config = config; + } + + public string Serialize(TOwner obj) + { + _processedObjects.Clear(); + return SerializeObject(obj, 0); + } + + private string? SerializeObject(object? obj, int nestingLevel) + { + if (obj == null) + return "null" + Environment.NewLine; + + if (obj.GetType().IsValueType || obj is string) + { + return TrySerializeFinalType(obj, out var serializedFinalType) + ? serializedFinalType + : obj.ToString() + Environment.NewLine; + } + + if (_processedObjects.Contains(obj)) + return "Circular Reference" + Environment.NewLine; + + _processedObjects.Add(obj); + + if (TrySerializeFinalType(obj, out var serializedFinal)) + return serializedFinal!; + + if (TrySerializeCollection(obj, nestingLevel, out var serializedCollection)) + return serializedCollection!; + + return SerializeComplexType(obj, nestingLevel); + } + + + private bool TrySerializeFinalType(object obj, out string? serializedFinalType) + { + var type = obj.GetType(); + + if (type.IsPrimitive || obj is string || obj is DateTime || obj is TimeSpan || obj is Guid) + { + serializedFinalType = obj switch + { + IFormattable formattable when _config.TypeCultures.TryGetValue(type, out var culture) => + formattable.ToString(null, culture), + IFormattable formattable => formattable.ToString(null, CultureInfo.InvariantCulture), + _ => obj.ToString() ?? "" + }; + + serializedFinalType += Environment.NewLine; + return true; + } + + serializedFinalType = null; + return false; + } + + private bool TrySerializeCollection(object obj, int nestingLevel, out string? serializedCollection) + { + if (obj is IDictionary dictionary) + { + serializedCollection = SerializeDictionary(dictionary, nestingLevel); + return true; + } + + if (obj is not IEnumerable collection) + { + serializedCollection = null; + return false; + } + + var builder = new StringBuilder(); + var indentation = new string(tab, nestingLevel + 1); + + builder.AppendLine(GetCollectionTypeName(obj) + ":"); + foreach (var item in collection) + builder.Append(indentation + SerializeObject(item, nestingLevel + 1)); + + serializedCollection = builder.ToString(); + return true; + } + + private string SerializeDictionary(IDictionary dictionary, int nestingLevel) + { + var builder = new StringBuilder(); + var indentation = new string(tab, nestingLevel + 1); + + builder.AppendLine(GetCollectionTypeName(dictionary) + ":"); + bool isFirstEntry = true; + + foreach (DictionaryEntry entry in dictionary) + { + if (!isFirstEntry) + { + builder.AppendLine(); + } + + builder.AppendLine(indentation + "KeyValuePair"); + builder.AppendLine(indentation + "\tKey = " + SerializeObject(entry.Key, nestingLevel + 2).TrimEnd()); + builder.Append(indentation + "\tValue = " + SerializeObject(entry.Value, nestingLevel + 2).TrimEnd()); + + isFirstEntry = false; + } + + return builder.ToString(); + } + + + + private string SerializeComplexType(object obj, int nestingLevel) + { + var builder = new StringBuilder(); + var indentation = new string(tab, nestingLevel + 1); + var type = obj.GetType(); + + builder.AppendLine(type.Name); + + foreach (var property in type.GetProperties()) + { + if (_config.ExcludedTypes.Contains(property.PropertyType) || + _config.ExcludedProperties.Contains(property.Name)) + continue; + + var value = SerializeProperty(property, obj, nestingLevel); + builder.Append(indentation + property.Name + " = " + value); + } + + return builder.ToString(); + } + + private string SerializeProperty(PropertyInfo property, object obj, int nestingLevel) + { + var value = property.GetValue(obj); + + if (_config.TypeSerializationMethods.TryGetValue(property.PropertyType, out var typeSerializer)) + return typeSerializer(value!) + Environment.NewLine; + + if (_config.PropertySerializationMethods.TryGetValue(property.Name, out var propertySerializer)) + return propertySerializer(value!) + Environment.NewLine; + + if (_config.PropertyLengths.TryGetValue(property.Name, out var length)) + { + var stringValue = value?.ToString() ?? ""; + return stringValue.Substring(0, Math.Min(length, stringValue.Length)) + Environment.NewLine; + } + + if (_config.PropertyCultures.TryGetValue(property.Name, out var culture) && value is IFormattable formattable) + return formattable.ToString(null, culture) + Environment.NewLine; + + return SerializeObject(value, nestingLevel); + } + + static string GetCollectionTypeName(object obj) + { + if (obj == null) throw new ArgumentNullException(nameof(obj)); + + var type = obj.GetType(); + + if (type.IsGenericType) + { + return type.GetGenericTypeDefinition().Name.Split('`')[0]; + } + else if (type.IsArray) + { + return $"{type.GetElementType().Name}[]"; + } + else + { + return type.Name; + } + } +} + diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index 0faa397e..dbbf92b4 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -1,28 +1,13 @@ -using System; -using System.Collections; -using System.Collections.Generic; +using ObjectPrinting; using System.Globalization; using System.Linq.Expressions; -using System.Reflection; -using System.Text; +using System; -namespace ObjectPrinting; public class PrintingConfig { - private readonly HashSet finalTypes = - [ - typeof(string), typeof(DateTime), typeof(TimeSpan), typeof(Guid) - ]; - private readonly HashSet excludedTypes = []; - private readonly Dictionary> typeSerializationMethods = []; - private readonly Dictionary typeCultures = []; - private readonly Dictionary propertyCultures = []; - private readonly Dictionary> propertySerializationMethods = []; - private readonly HashSet excludedProperties = []; - private readonly HashSet processedObjects = []; - private readonly Dictionary propertyLengths = new(); - + private readonly PrintingConfigStorage _config = new(); + public PropertyPrintingConfig Printing() { return new PropertyPrintingConfig(this); @@ -30,186 +15,51 @@ public PropertyPrintingConfig Printing() public PropertyPrintingConfig Printing(Expression> memberSelector) { - var propertyName = GetPropertyName(memberSelector); - + var propertyName = ReflectionHelper.GetPropertyName(memberSelector); return new PropertyPrintingConfig(this, propertyName); } - public string PrintToString(TOwner obj) - { - return PrintToString(obj, 0); - } - - private string PrintToString(object? obj, int nestingLevel) - { - if (obj == null) - { - return "null" + Environment.NewLine; - } - - if (processedObjects.Contains(obj)) - { - return "Circular Reference" + Environment.NewLine; - } - - if (TrySerializeFinalType(obj, out var serializedFinalType)) - { - return serializedFinalType!; - } - - if (TrySerializeCollection(obj, nestingLevel, out var serializedCollection)) - { - return serializedCollection!; - } - - return SerializeComplexType(obj, nestingLevel); - } - public PrintingConfig Excluding() { - excludedTypes.Add(typeof(TPropType)); + _config.ExcludedTypes.Add(typeof(TPropType)); return this; } public PrintingConfig Excluding(Expression> memberSelector) { - var propertyName = GetPropertyName(memberSelector); - excludedProperties.Add(propertyName); + var propertyName = ReflectionHelper.GetPropertyName(memberSelector); + _config.ExcludedProperties.Add(propertyName); return this; } public void SpecifyTheCulture(CultureInfo culture) { - typeCultures[typeof(TType)] = culture; + _config.TypeCultures[typeof(TType)] = culture; } - + public void SpecifyTheCulture(CultureInfo culture, string propertyName) { - propertyCultures[propertyName] = culture; + _config.PropertyCultures[propertyName] = culture; } public void AddSerializationMethod(Func serializationMethod) { - typeSerializationMethods[typeof(TType)] = obj => serializationMethod((TType)obj); + _config.TypeSerializationMethods[typeof(TType)] = obj => serializationMethod((TType)obj); } public void AddSerializationMethod(Func serializationMethod, string propertyName) { - propertySerializationMethods[propertyName] = obj => serializationMethod((TType)obj); + _config.PropertySerializationMethods[propertyName] = obj => serializationMethod((TType)obj); } public void AddLengthProperty(string propertyName, int trimLength) { - propertyLengths[propertyName] = trimLength; + _config.PropertyLengths[propertyName] = trimLength; } - private bool TrySerializeFinalType(object obj, out string? serializedFinalType) - { - var type = obj.GetType(); - - if (!finalTypes.Contains(type) && !type.IsPrimitive) - { - serializedFinalType = null; - return false; - } - - serializedFinalType = obj switch - { - IFormattable format when typeCultures.TryGetValue(type, out var formatProvider) => - format.ToString(null, formatProvider), - IFormattable format => - format.ToString(null, CultureInfo.InvariantCulture), - string str => str, - _ => Convert.ToString(obj) - }; - - serializedFinalType += Environment.NewLine; - - return true; - } - - private bool TrySerializeCollection(object obj, int nestingLevel, out string? serializedCollection) - { - if (obj is not IEnumerable collection) - { - serializedCollection = null; - return false; - } - - var collectionOnString = new StringBuilder(); - var indentation = new string('\t', nestingLevel + 1); - var type = obj.GetType(); - - collectionOnString.AppendLine($"{type.Name}:"); - - foreach (var item in collection) - { - collectionOnString.Append(indentation + PrintToString(item, nestingLevel + 1)); - } - - serializedCollection = collectionOnString.ToString(); - return true; - } - - private string SerializeComplexType(object obj, int nestingLevel) - { - processedObjects.Add(obj); - var serializedString = new StringBuilder(); - var indentation = new string('\t', nestingLevel + 1); - var type = obj.GetType(); - - serializedString.AppendLine(type.Name); - - foreach (var property in type.GetProperties()) - { - if (excludedTypes.Contains(property.PropertyType) || excludedProperties.Contains(property.Name)) - { - continue; - } - - var serializedProperty = SerializeProperty(property, obj, nestingLevel + 1); - serializedString.Append(indentation + property.Name + " = " + serializedProperty); - } - - return serializedString.ToString(); - } - - private string SerializeProperty(PropertyInfo property, object obj, int nestingLevel) - { - var propertyValue = property.GetValue(obj); - - if (typeSerializationMethods.TryGetValue(property.PropertyType, out var serializationType)) - { - return serializationType(propertyValue!) + Environment.NewLine; - } - - if (propertySerializationMethods.TryGetValue(property.Name, out var serializationProperty)) - { - return serializationProperty(propertyValue!) + Environment.NewLine; - } - - if (propertyLengths.TryGetValue(property.Name, out var length)) - { - var stringPropertyValue = Convert.ToString(propertyValue)!; - - return stringPropertyValue[..length] + Environment.NewLine; - } - - if (propertyCultures.TryGetValue(property.Name, out var formatProvider) && propertyValue is IFormattable format) - { - return format.ToString(null, formatProvider) + Environment.NewLine; - } - - return PrintToString(propertyValue, nestingLevel); - } - - private static string GetPropertyName(Expression> property) + public string PrintToString(TOwner obj) { - if (property.Body is MemberExpression member) - { - return member.Member.Name; - } - - throw new ArgumentException("Expression is not property."); + var serializer = new ObjectSerializer(_config); + return serializer.Serialize(obj); } -} \ No newline at end of file +} diff --git a/ObjectPrinting/PrintingConfigStorage.cs b/ObjectPrinting/PrintingConfigStorage.cs new file mode 100644 index 00000000..3fb60ab9 --- /dev/null +++ b/ObjectPrinting/PrintingConfigStorage.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System; + +public class PrintingConfigStorage +{ + public HashSet ExcludedTypes { get; } = new(); + public Dictionary> TypeSerializationMethods { get; } = new(); + public Dictionary TypeCultures { get; } = new(); + public Dictionary PropertyCultures { get; } = new(); + public Dictionary> PropertySerializationMethods { get; } = new(); + public HashSet ExcludedProperties { get; } = new(); + public Dictionary PropertyLengths { get; } = new(); +} diff --git a/ObjectPrinting/ReflectionHelper.cs b/ObjectPrinting/ReflectionHelper.cs new file mode 100644 index 00000000..f204d384 --- /dev/null +++ b/ObjectPrinting/ReflectionHelper.cs @@ -0,0 +1,12 @@ +using System.Linq.Expressions; +using System; +public static class ReflectionHelper +{ + public static string GetPropertyName(Expression> propertyExpression) + { + if (propertyExpression.Body is MemberExpression member) + return member.Member.Name; + + throw new ArgumentException("Expression is not a property."); + } +} diff --git a/Samples/Spectacle/Program.cs b/Samples/Spectacle/Program.cs index 33717d2b..bd60768e 100644 --- a/Samples/Spectacle/Program.cs +++ b/Samples/Spectacle/Program.cs @@ -4,18 +4,18 @@ namespace SpectacleSample { public class Program { - public static void Main() - { - var spectacle = new Spectacle() - .Say("Привет мир!") - .Delay(TimeSpan.FromSeconds(1)) - .UntilKeyPressed(s => - s.TypeText("тра-ля-ля") - .TypeText("тру-лю-лю") - ) - .Say("Пока-пока!"); + //public static void Main() + //{ + // var spectacle = new Spectacle() + // .Say("Привет мир!") + // .Delay(TimeSpan.FromSeconds(1)) + // .UntilKeyPressed(s => + // s.TypeText("тра-ля-ля") + // .TypeText("тру-лю-лю") + // ) + // .Say("Пока-пока!"); - spectacle.Play(); - } + // spectacle.Play(); + //} } } \ No newline at end of file diff --git a/Test/Test.csproj b/Test/Test.csproj new file mode 100644 index 00000000..8b5797ec --- /dev/null +++ b/Test/Test.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + diff --git a/ObjectPrinting/Tests/ObjectPrinterTests.cs b/Test/Tests/ObjectPrinterTests.cs similarity index 100% rename from ObjectPrinting/Tests/ObjectPrinterTests.cs rename to Test/Tests/ObjectPrinterTests.cs diff --git a/ObjectPrinting/Tests/Person.cs b/Test/Tests/Person.cs similarity index 100% rename from ObjectPrinting/Tests/Person.cs rename to Test/Tests/Person.cs diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt similarity index 100% rename from ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt rename to Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt diff --git a/Tests/ObjectPrinterTests.cs b/Tests/ObjectPrinterTests.cs new file mode 100644 index 00000000..fe58112b --- /dev/null +++ b/Tests/ObjectPrinterTests.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using NUnit.Framework; +using ObjectPrinting; +using ObjectPrinting.Extensions; +using VerifyNUnit; +using VerifyTests; + +namespace Tests +{ + [TestFixture] + public class ObjectPrinterTests + { + private static readonly VerifySettings Settings = new(); + private Person person; + + [SetUp] + public void Setup() + { + Settings.UseDirectory("snapshots"); + person = new Person + { + Name = "Bob", + Age = 20, + Height = 200, + Weight = 100, + Birthday = new DateTime(2000, 10, 10), + IsStudent = true + }; + } + + [Test] + public Task PrintToString_ExcludeType() + { + var actual = ObjectPrinter.For() + .Excluding() + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_AlternativeTypeSerialization() + { + var actual = ObjectPrinter.For() + .Printing() + .Using(_ => "date") + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SetCultureForType() + { + person.Height = 200.2; + person.Weight = 100.11; + var russianCulture = new CultureInfo("ru-RU"); + + var actual = ObjectPrinter.For() + .Printing() + .Using(russianCulture) + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SetCultureForProperty() + { + person.Height = 200.2; + person.Weight = 100.11; + var russianCulture = new CultureInfo("ru-RU"); + + var actual = ObjectPrinter.For() + .Printing(p => p.Height) + .Using(russianCulture) + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_AlternativePropertySerialization() + { + var actual = ObjectPrinter.For() + .Printing(p => p.Name) + .Using(_ => "NoName") + .Printing(p => p.Id) + .Using(_ => "12345") + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_Trim() + { + var actual = ObjectPrinter.For() + .Printing(p => p.Name) + .TrimmedToLength(2) + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_ExcludeProperty() + { + var actual = ObjectPrinter.For() + .Excluding(p => p.Id) + .PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_CircularReference() + { + person.Father = person; + + var actual = ObjectPrinter.For().PrintToString(person); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SerializeArray() + { + var persons = new[] + { + person, + new() + { + Name = "Bread", + Age = 22, + Height = 222, + Weight = 111, + Birthday = new DateTime(2001, 11, 11), + IsStudent = false + } + }; + + var actual = ObjectPrinter.For().PrintToString(persons); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_Correct_WhenCallAllMethods() + { + person.Height = 200.2; + person.Weight = 100.11; + var russianCulture = new CultureInfo("ru-RU"); + var actual = ObjectPrinter.For() + .Excluding() + .Excluding(p => p.Id) + .Printing() + .Using(_ => "date") + .Printing() + .Using(russianCulture) + .Printing(p => p.Name) + .TrimmedToLength(2) + .PrintToString(person); + + return Verifier.Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SerializeList() + { + var persons = new List + { + person, + new() + { + Id = new Guid("11111122-1234-1234-1234-000000000000"), + Name = "Bread", + Age = 22, + Height = 222, + Weight = 111, + Birthday = new DateTime(2001, 11, 11), + IsStudent = false + } + }; + + var actual = ObjectPrinter.For>().PrintToString(persons); + + return Verify(actual, Settings); + } + + [Test] + public Task PrintToString_SerializeDictionary() + { + var persons = new Dictionary + { + { person, "first" }, + { + new() + { + Name = "Bread", + Age = 22, + Height = 222, + Weight = 111, + Birthday = new DateTime(2001, 11, 11), + IsStudent = false + }, + "second" + } + }; + + var actual = ObjectPrinter.For>().PrintToString(persons); + + return Verify(actual, Settings); + } + } +} diff --git a/Tests/Person.cs b/Tests/Person.cs new file mode 100644 index 00000000..8e80d29c --- /dev/null +++ b/Tests/Person.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tests +{ + public class Person + { + public Guid Id { get; set; } + + public string Name { get; set; } + + public double Height { get; set; } + + public double Weight { get; set; } + + public int Age { get; set; } + + public DateTime Birthday { get; set; } + + public bool IsStudent { get; set; } + + public Person? Father { get; set; } + } +} diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt new file mode 100644 index 00000000..c74966bc --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 12345 + Name = NoName + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt new file mode 100644 index 00000000..f0a7c193 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = date + IsStudent = True + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt new file mode 100644 index 00000000..5b7723d5 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = Circular Reference diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt new file mode 100644 index 00000000..a3d4259c --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt @@ -0,0 +1,7 @@ +Person + Name = Bo + Height = 200,2 + Weight = 100,11 + Age = 20 + Birthday = date + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt new file mode 100644 index 00000000..8226d328 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt @@ -0,0 +1,8 @@ +Person + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt new file mode 100644 index 00000000..94d0a158 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt @@ -0,0 +1,8 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt new file mode 100644 index 00000000..3feff897 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt @@ -0,0 +1,19 @@ +Person[]: + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bread + Height = 222 + Weight = 111 + Age = 22 + Birthday = 11/11/2001 00:00:00 + IsStudent = False + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt new file mode 100644 index 00000000..b0c41f9a --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt @@ -0,0 +1,23 @@ +Dictionary: + KeyValuePair + Key = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null + Value = first + KeyValuePair + Key = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bread + Height = 222 + Weight = 111 + Age = 22 + Birthday = 11/11/2001 00:00:00 + IsStudent = False + Father = null + Value = second diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt new file mode 100644 index 00000000..b661d5ce --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt @@ -0,0 +1,19 @@ +List: + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null + Person + Id = 11111122-1234-1234-1234-000000000000 + Name = Bread + Height = 222 + Weight = 111 + Age = 22 + Birthday = 11/11/2001 00:00:00 + IsStudent = False + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt new file mode 100644 index 00000000..9091c50c --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200,2 + Weight = 100.11 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt new file mode 100644 index 00000000..878e54b1 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bob + Height = 200,2 + Weight = 100,11 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt new file mode 100644 index 00000000..0a320f44 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Bo + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git "a/Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" "b/Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" new file mode 100644 index 00000000..c74966bc --- /dev/null +++ "b/Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" @@ -0,0 +1,9 @@ +Person + Id = 12345 + Name = NoName + Height = 200 + Weight = 100 + Age = 20 + Birthday = 10/10/2000 00:00:00 + IsStudent = True + Father = null diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj new file mode 100644 index 00000000..a5cc06f6 --- /dev/null +++ b/Tests/Tests.csproj @@ -0,0 +1,40 @@ + + + + net8.0 + enable + enable + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + $([System.String]::Copy('%(FileName)').Split('.')[0].Split('(')[0]) + %(ParentFile).cs + + + + diff --git a/fluent-api.sln b/fluent-api.sln index 69c8db9e..58d8c5b6 100644 --- a/fluent-api.sln +++ b/fluent-api.sln @@ -1,17 +1,19 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35303.130 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectPrinting", "ObjectPrinting\ObjectPrinting.csproj", "{07B8C9B7-8289-46CB-9875-048A57758EEE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectPrinting", "ObjectPrinting\ObjectPrinting.csproj", "{07B8C9B7-8289-46CB-9875-048A57758EEE}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{6D308E4A-CEC7-4536-9B87-81CD337A87AD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentMapping", "Samples\FluentMapper\FluentMapping.csproj", "{FEEA5AFE-459A-4D13-81D0-252E1A2E6F4E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentMapping", "Samples\FluentMapper\FluentMapping.csproj", "{FEEA5AFE-459A-4D13-81D0-252E1A2E6F4E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentMapping.Tests", "Samples\FluentMapper.Tests\FluentMapping.Tests.csproj", "{8A7BB3EA-3E6A-4D04-A801-D5CD1620DA0D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentMapping.Tests", "Samples\FluentMapper.Tests\FluentMapping.Tests.csproj", "{8A7BB3EA-3E6A-4D04-A801-D5CD1620DA0D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spectacle", "Samples\Spectacle\Spectacle.csproj", "{EFA9335C-411B-4597-B0B6-5438D1AE04C3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectacle", "Samples\Spectacle\Spectacle.csproj", "{EFA9335C-411B-4597-B0B6-5438D1AE04C3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{0A6EEC4E-959A-4378-A8A9-B965F5F7D7FB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -35,6 +37,10 @@ Global {EFA9335C-411B-4597-B0B6-5438D1AE04C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {EFA9335C-411B-4597-B0B6-5438D1AE04C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {EFA9335C-411B-4597-B0B6-5438D1AE04C3}.Release|Any CPU.Build.0 = Release|Any CPU + {0A6EEC4E-959A-4378-A8A9-B965F5F7D7FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A6EEC4E-959A-4378-A8A9-B965F5F7D7FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A6EEC4E-959A-4378-A8A9-B965F5F7D7FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A6EEC4E-959A-4378-A8A9-B965F5F7D7FB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -44,4 +50,7 @@ Global {8A7BB3EA-3E6A-4D04-A801-D5CD1620DA0D} = {6D308E4A-CEC7-4536-9B87-81CD337A87AD} {EFA9335C-411B-4597-B0B6-5438D1AE04C3} = {6D308E4A-CEC7-4536-9B87-81CD337A87AD} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {950AF03C-624E-4B6E-A59F-068BFFC45369} + EndGlobalSection EndGlobal From d447451dc0d49341c7fbf68f29f2569b065dd460 Mon Sep 17 00:00:00 2001 From: Emi1337-ops Date: Thu, 12 Dec 2024 19:12:13 +0500 Subject: [PATCH 3/4] Fix mistakes --- Test/Test.csproj | 24 -- Test/Tests/ObjectPrinterTests.cs | 214 ------------------ Test/Tests/Person.cs | 22 -- ...ernativePropertySerialization.verified.txt | 9 - ..._AlternativeTypeSerialization.verified.txt | 9 - ...intToString_CircularReference.verified.txt | 9 - ...ng_Correct_WhenCallAllMethods.verified.txt | 7 - ...PrintToString_ExcludeProperty.verified.txt | 8 - ...sts.PrintToString_ExcludeType.verified.txt | 8 - ....PrintToString_SerializeArray.verified.txt | 19 -- ...tToString_SerializeDictionary.verified.txt | 23 -- ...s.PrintToString_SerializeList.verified.txt | 19 -- ...oString_SetCultureForProperty.verified.txt | 9 - ...intToString_SetCultureForType.verified.txt | 9 - ...interTests.PrintToString_Trim.verified.txt | 9 - Tests/ObjectPrinterTests.cs | 3 +- ...ng_Correct_WhenCallAllMethods.verified.txt | 1 + ...g_Correct_WhenCallAllMethods.verified.txt" | 9 - 18 files changed, 3 insertions(+), 408 deletions(-) delete mode 100644 Test/Test.csproj delete mode 100644 Test/Tests/ObjectPrinterTests.cs delete mode 100644 Test/Tests/Person.cs delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt delete mode 100644 Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt delete mode 100644 "Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" diff --git a/Test/Test.csproj b/Test/Test.csproj deleted file mode 100644 index 8b5797ec..00000000 --- a/Test/Test.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net8.0 - enable - enable - - false - true - - - - - - - - - - - - - - - diff --git a/Test/Tests/ObjectPrinterTests.cs b/Test/Tests/ObjectPrinterTests.cs deleted file mode 100644 index 8726516e..00000000 --- a/Test/Tests/ObjectPrinterTests.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Threading.Tasks; -using NUnit.Framework; -using ObjectPrinting.Extensions; -using VerifyNUnit; -using VerifyTests; - -namespace ObjectPrinting.Tests; - -[TestFixture] -public class ObjectPrinterTests -{ - private static readonly VerifySettings Settings = new(); - private Person person; - - [SetUp] - public void Setup() - { - Settings.UseDirectory("snapshots"); - person = new Person - { - Name = "Bob", - Age = 20, - Height = 200, - Weight = 100, - Birthday = new DateTime(2000, 10, 10), - IsStudent = true - }; - } - - [Test] - public Task PrintToString_ExcludeType() - { - var actual = ObjectPrinter.For() - .Excluding() - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_Correct_WhenCallAllMethods() - { - person.Height = 200.2; - person.Weight = 100.11; - var russianCulture = new CultureInfo("ru-RU"); - var actual = ObjectPrinter.For() - .Excluding() - .Excluding(p => p.Id) - .Printing() - .Using(_ => "date") - .Printing() - .Using(russianCulture) - .Printing(p => p.Name) - .TrimmedToLength(2) - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_AlternativeTypeSerialization() - { - var actual = ObjectPrinter.For() - .Printing() - .Using(_ => "date") - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_SetCultureForType() - { - person.Height = 200.2; - person.Weight = 100.11; - var russianCulture = new CultureInfo("ru-RU"); - - var actual = ObjectPrinter.For() - .Printing() - .Using(russianCulture) - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_SetCultureForProperty() - { - person.Height = 200.2; - person.Weight = 100.11; - var russianCulture = new CultureInfo("ru-RU"); - - var actual = ObjectPrinter.For() - .Printing(p => p.Height) - .Using(russianCulture) - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_AlternativePropertySerialization() - { - var actual = ObjectPrinter.For() - .Printing(p => p.Name) - .Using(_ => "NoName") - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_Trim() - { - var actual = ObjectPrinter.For() - .Printing(p => p.Name) - .TrimmedToLength(2) - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_ExcludeProperty() - { - var actual = ObjectPrinter.For() - .Excluding(p => p.Id) - .PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_CircularReference() - { - person.Father = person; - - var actual = ObjectPrinter.For().PrintToString(person); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_SerializeArray() - { - var persons = new[] - { - person, - new() - { - Name = "Bread", - Age = 22, - Height = 222, - Weight = 111, - Birthday = new DateTime(2001, 11, 11), - IsStudent = false - } - }; - - var actual = ObjectPrinter.For().PrintToString(persons); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_SerializeList() - { - var persons = new List - { - person, - new() - { - Name = "Bread", - Age = 22, - Height = 222, - Weight = 111, - Birthday = new DateTime(2001, 11, 11), - IsStudent = false - } - }; - - var actual = ObjectPrinter.For>().PrintToString(persons); - - return Verifier.Verify(actual, Settings); - } - - [Test] - public Task PrintToString_SerializeDictionary() - { - var persons = new Dictionary - { - { person, "first" }, - { - new() - { - Name = "Bread", - Age = 22, - Height = 222, - Weight = 111, - Birthday = new DateTime(2001, 11, 11), - IsStudent = false - }, - "second" - } - }; - - var actual = ObjectPrinter.For>().PrintToString(persons); - - return Verifier.Verify(actual, Settings); - } -} \ No newline at end of file diff --git a/Test/Tests/Person.cs b/Test/Tests/Person.cs deleted file mode 100644 index da8b234b..00000000 --- a/Test/Tests/Person.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace ObjectPrinting.Tests; - -public class Person -{ - public Guid Id { get; set; } - - public string Name { get; set; } - - public double Height { get; set; } - - public double Weight { get; set; } - - public int Age { get; set; } - - public DateTime Birthday { get; set; } - - public bool IsStudent { get; set; } - - public Person? Father { get; set; } -} \ No newline at end of file diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt deleted file mode 100644 index eca95843..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified.txt +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = NoName - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt deleted file mode 100644 index f0a7c193..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_AlternativeTypeSerialization.verified.txt +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200 - Weight = 100 - Age = 20 - Birthday = date - IsStudent = True - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt deleted file mode 100644 index 5b7723d5..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_CircularReference.verified.txt +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = Circular Reference diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt deleted file mode 100644 index a3d4259c..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt +++ /dev/null @@ -1,7 +0,0 @@ -Person - Name = Bo - Height = 200,2 - Weight = 100,11 - Age = 20 - Birthday = date - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt deleted file mode 100644 index 8226d328..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeProperty.verified.txt +++ /dev/null @@ -1,8 +0,0 @@ -Person - Name = Bob - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt deleted file mode 100644 index 94d0a158..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_ExcludeType.verified.txt +++ /dev/null @@ -1,8 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200 - Weight = 100 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt deleted file mode 100644 index 3feff897..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeArray.verified.txt +++ /dev/null @@ -1,19 +0,0 @@ -Person[]: - Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null - Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bread - Height = 222 - Weight = 111 - Age = 22 - Birthday = 11/11/2001 00:00:00 - IsStudent = False - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt deleted file mode 100644 index 9797b02d..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeDictionary.verified.txt +++ /dev/null @@ -1,23 +0,0 @@ -Dictionary`2: - KeyValuePair`2 - Key = Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null - Value = first - KeyValuePair`2 - Key = Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bread - Height = 222 - Weight = 111 - Age = 22 - Birthday = 11/11/2001 00:00:00 - IsStudent = False - Father = null - Value = second diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt deleted file mode 100644 index 498a0de8..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SerializeList.verified.txt +++ /dev/null @@ -1,19 +0,0 @@ -List`1: - Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null - Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bread - Height = 222 - Weight = 111 - Age = 22 - Birthday = 11/11/2001 00:00:00 - IsStudent = False - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt deleted file mode 100644 index 9091c50c..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForProperty.verified.txt +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200,2 - Weight = 100.11 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt deleted file mode 100644 index 878e54b1..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_SetCultureForType.verified.txt +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bob - Height = 200,2 - Weight = 100,11 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null diff --git a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt b/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt deleted file mode 100644 index 0a320f44..00000000 --- a/Test/Tests/Snapshots/ObjectPrinterTests.PrintToString_Trim.verified.txt +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 00000000-0000-0000-0000-000000000000 - Name = Bo - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null diff --git a/Tests/ObjectPrinterTests.cs b/Tests/ObjectPrinterTests.cs index fe58112b..00693a7f 100644 --- a/Tests/ObjectPrinterTests.cs +++ b/Tests/ObjectPrinterTests.cs @@ -156,7 +156,8 @@ public Task PrintToString_Correct_WhenCallAllMethods() var russianCulture = new CultureInfo("ru-RU"); var actual = ObjectPrinter.For() .Excluding() - .Excluding(p => p.Id) + .Printing(x => x.Id) + .Using(_ => "12345") .Printing() .Using(_ => "date") .Printing() diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt index a3d4259c..1a2e9156 100644 --- a/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt @@ -1,4 +1,5 @@ Person + Id = 12345 Name = Bo Height = 200,2 Weight = 100,11 diff --git "a/Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" "b/Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" deleted file mode 100644 index c74966bc..00000000 --- "a/Tests/Snapshots/ObjectPrinterTests\321\216PrintToString_Correct_WhenCallAllMethods.verified.txt" +++ /dev/null @@ -1,9 +0,0 @@ -Person - Id = 12345 - Name = NoName - Height = 200 - Weight = 100 - Age = 20 - Birthday = 10/10/2000 00:00:00 - IsStudent = True - Father = null From 5607fcde971110be656666e59317275c08c110e5 Mon Sep 17 00:00:00 2001 From: Emi1337-ops Date: Fri, 13 Dec 2024 00:11:13 +0500 Subject: [PATCH 4/4] Add Solution for Nestin Property --- .../PropertyPrintingConfigExtensions.cs | 4 +-- ObjectPrinting/ObjectSerializer.cs | 10 +++---- ObjectPrinting/PrintingConfig.cs | 19 +++++++------- ObjectPrinting/PrintingConfigStorage.cs | 9 ++++--- ObjectPrinting/PropertyPrintingConfig.cs | 15 ++++++----- ObjectPrinting/ReflectionHelper.cs | 26 ++++++++++++++++--- Tests/ObjectPrinterTests.cs | 15 +++++++++++ Tests/Persons.cs | 21 +++++++++++++++ ...SkipProperty_WhenNestingClass.verified.txt | 4 +++ 9 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 Tests/Persons.cs create mode 100644 Tests/Snapshots/ObjectPrinterTests.PrintToString_NotSkipProperty_WhenNestingClass.verified.txt diff --git a/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs b/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs index 4627b89c..dcbcb960 100644 --- a/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs +++ b/ObjectPrinting/Extensions/PropertyPrintingConfigExtensions.cs @@ -8,10 +8,10 @@ public static PrintingConfig TrimmedToLength( this PropertyPrintingConfig propConfig, int maxLen) { - if (string.IsNullOrEmpty(propConfig.PropertyName)) + if (propConfig.Property is null) throw new ArgumentException("The name of the property is not specified."); - propConfig.ParentConfig.AddLengthProperty(propConfig.PropertyName, maxLen); + propConfig.ParentConfig.AddLengthProperty(propConfig.Property, maxLen); return propConfig.ParentConfig; } diff --git a/ObjectPrinting/ObjectSerializer.cs b/ObjectPrinting/ObjectSerializer.cs index 1c08dc04..484aac61 100644 --- a/ObjectPrinting/ObjectSerializer.cs +++ b/ObjectPrinting/ObjectSerializer.cs @@ -134,10 +134,10 @@ private string SerializeComplexType(object obj, int nestingLevel) foreach (var property in type.GetProperties()) { if (_config.ExcludedTypes.Contains(property.PropertyType) || - _config.ExcludedProperties.Contains(property.Name)) + _config.ExcludedProperties.Contains(property)) continue; - var value = SerializeProperty(property, obj, nestingLevel); + var value = SerializeProperty(property, obj, nestingLevel+1); builder.Append(indentation + property.Name + " = " + value); } @@ -151,16 +151,16 @@ private string SerializeProperty(PropertyInfo property, object obj, int nestingL if (_config.TypeSerializationMethods.TryGetValue(property.PropertyType, out var typeSerializer)) return typeSerializer(value!) + Environment.NewLine; - if (_config.PropertySerializationMethods.TryGetValue(property.Name, out var propertySerializer)) + if (_config.PropertySerializationMethods.TryGetValue(property, out var propertySerializer)) return propertySerializer(value!) + Environment.NewLine; - if (_config.PropertyLengths.TryGetValue(property.Name, out var length)) + if (_config.PropertyLengths.TryGetValue(property, out var length)) { var stringValue = value?.ToString() ?? ""; return stringValue.Substring(0, Math.Min(length, stringValue.Length)) + Environment.NewLine; } - if (_config.PropertyCultures.TryGetValue(property.Name, out var culture) && value is IFormattable formattable) + if (_config.PropertyCultures.TryGetValue(property, out var culture) && value is IFormattable formattable) return formattable.ToString(null, culture) + Environment.NewLine; return SerializeObject(value, nestingLevel); diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index dbbf92b4..44f0aa61 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -2,6 +2,7 @@ using System.Globalization; using System.Linq.Expressions; using System; +using System.Reflection; public class PrintingConfig @@ -15,7 +16,7 @@ public PropertyPrintingConfig Printing() public PropertyPrintingConfig Printing(Expression> memberSelector) { - var propertyName = ReflectionHelper.GetPropertyName(memberSelector); + var propertyName = ReflectionHelper.GetProperty(memberSelector); return new PropertyPrintingConfig(this, propertyName); } @@ -27,8 +28,8 @@ public PrintingConfig Excluding() public PrintingConfig Excluding(Expression> memberSelector) { - var propertyName = ReflectionHelper.GetPropertyName(memberSelector); - _config.ExcludedProperties.Add(propertyName); + var property = ReflectionHelper.GetProperty(memberSelector); + _config.ExcludedProperties.Add(property); return this; } @@ -37,9 +38,9 @@ public void SpecifyTheCulture(CultureInfo culture) _config.TypeCultures[typeof(TType)] = culture; } - public void SpecifyTheCulture(CultureInfo culture, string propertyName) + public void SpecifyTheCulture(CultureInfo culture, PropertyInfo property) { - _config.PropertyCultures[propertyName] = culture; + _config.PropertyCultures[property] = culture; } public void AddSerializationMethod(Func serializationMethod) @@ -47,14 +48,14 @@ public void AddSerializationMethod(Func serializationMetho _config.TypeSerializationMethods[typeof(TType)] = obj => serializationMethod((TType)obj); } - public void AddSerializationMethod(Func serializationMethod, string propertyName) + public void AddSerializationMethod(Func serializationMethod, PropertyInfo property) { - _config.PropertySerializationMethods[propertyName] = obj => serializationMethod((TType)obj); + _config.PropertySerializationMethods[property] = obj => serializationMethod((TType)obj); } - public void AddLengthProperty(string propertyName, int trimLength) + public void AddLengthProperty(PropertyInfo property, int trimLength) { - _config.PropertyLengths[propertyName] = trimLength; + _config.PropertyLengths[property] = trimLength; } public string PrintToString(TOwner obj) diff --git a/ObjectPrinting/PrintingConfigStorage.cs b/ObjectPrinting/PrintingConfigStorage.cs index 3fb60ab9..e61da008 100644 --- a/ObjectPrinting/PrintingConfigStorage.cs +++ b/ObjectPrinting/PrintingConfigStorage.cs @@ -1,13 +1,14 @@ using System.Collections.Generic; using System; +using System.Reflection; public class PrintingConfigStorage { public HashSet ExcludedTypes { get; } = new(); public Dictionary> TypeSerializationMethods { get; } = new(); public Dictionary TypeCultures { get; } = new(); - public Dictionary PropertyCultures { get; } = new(); - public Dictionary> PropertySerializationMethods { get; } = new(); - public HashSet ExcludedProperties { get; } = new(); - public Dictionary PropertyLengths { get; } = new(); + public Dictionary PropertyCultures { get; } = new(); + public Dictionary> PropertySerializationMethods { get; } = new(); + public HashSet ExcludedProperties { get; } = new(); + public Dictionary PropertyLengths { get; } = new(); } diff --git a/ObjectPrinting/PropertyPrintingConfig.cs b/ObjectPrinting/PropertyPrintingConfig.cs index 4f1fc555..3777ae2f 100644 --- a/ObjectPrinting/PropertyPrintingConfig.cs +++ b/ObjectPrinting/PropertyPrintingConfig.cs @@ -1,28 +1,29 @@ using System; using System.Globalization; +using System.Reflection; namespace ObjectPrinting; public class PropertyPrintingConfig { private readonly PrintingConfig printingConfig; - protected internal readonly string? PropertyName; + protected internal readonly PropertyInfo? Property; - public PropertyPrintingConfig(PrintingConfig printingConfig, string? propertyName = null) + public PropertyPrintingConfig(PrintingConfig printingConfig, PropertyInfo? property = null) { this.printingConfig = printingConfig; - PropertyName = propertyName; + Property = property; } public PrintingConfig Using(Func print) { - if (string.IsNullOrEmpty(PropertyName)) + if (Property is null) { printingConfig.AddSerializationMethod(print); } else { - printingConfig.AddSerializationMethod(print, PropertyName); + printingConfig.AddSerializationMethod(print, Property); } return ParentConfig; @@ -30,13 +31,13 @@ public PrintingConfig Using(Func print) public PrintingConfig Using(CultureInfo culture) { - if (string.IsNullOrEmpty(PropertyName)) + if (Property is null) { printingConfig.SpecifyTheCulture(culture); } else { - printingConfig.SpecifyTheCulture(culture, PropertyName); + printingConfig.SpecifyTheCulture(culture, Property); } return ParentConfig; diff --git a/ObjectPrinting/ReflectionHelper.cs b/ObjectPrinting/ReflectionHelper.cs index f204d384..5c818770 100644 --- a/ObjectPrinting/ReflectionHelper.cs +++ b/ObjectPrinting/ReflectionHelper.cs @@ -1,12 +1,30 @@ using System.Linq.Expressions; using System; +using System.Reflection; public static class ReflectionHelper { - public static string GetPropertyName(Expression> propertyExpression) + public static PropertyInfo GetProperty(Expression> propertyExpression) { - if (propertyExpression.Body is MemberExpression member) - return member.Member.Name; + if (propertyExpression.Body is MemberExpression memberExpression) + { + if (memberExpression.Member is PropertyInfo propertyInfo) + { + return propertyInfo; + } + throw new ArgumentException("Expression is not a property", nameof(propertyExpression)); + } + throw new ArgumentException("Expression is not a MemberExpression.", nameof(propertyExpression)); + //if (propertyExpression.Body is MemberExpression member) + //{ + // var property = member as PropertyInfo; + // //var className = typeof(TOwner).Name; + + // var memberName = member.Member.Name; + // return memberName; + // //return $"{className} {memberName}"; + //} + - throw new ArgumentException("Expression is not a property."); + //throw new ArgumentException("Expression is not a property."); } } diff --git a/Tests/ObjectPrinterTests.cs b/Tests/ObjectPrinterTests.cs index 00693a7f..3eff435e 100644 --- a/Tests/ObjectPrinterTests.cs +++ b/Tests/ObjectPrinterTests.cs @@ -31,6 +31,21 @@ public void Setup() }; } + [Test] + public Task PrintToString_NotSkipProperty_WhenNestingClass() + { + var person2 = new Person2(); + var person1 = new Person1 + { + Parent = person2 + }; + var actual = ObjectPrinter.For() + .Excluding(x => x.Id) + .PrintToString(person1); + + return Verify(actual, Settings); + } + [Test] public Task PrintToString_ExcludeType() { diff --git a/Tests/Persons.cs b/Tests/Persons.cs new file mode 100644 index 00000000..9a13ec17 --- /dev/null +++ b/Tests/Persons.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tests +{ + public class Person1 + { + public Guid Id { get; set; } + + public Person2 Parent { get; set; } + } + + public class Person2 + { + public Guid Id { get; set; } + public string Name { get; set; } + } +} diff --git a/Tests/Snapshots/ObjectPrinterTests.PrintToString_NotSkipProperty_WhenNestingClass.verified.txt b/Tests/Snapshots/ObjectPrinterTests.PrintToString_NotSkipProperty_WhenNestingClass.verified.txt new file mode 100644 index 00000000..028950e2 --- /dev/null +++ b/Tests/Snapshots/ObjectPrinterTests.PrintToString_NotSkipProperty_WhenNestingClass.verified.txt @@ -0,0 +1,4 @@ +Person1 + Parent = Person2 + Id = 00000000-0000-0000-0000-000000000000 + Name = null