diff --git a/.gitignore b/.gitignore index a1f46668..4c1e8fdf 100644 --- a/.gitignore +++ b/.gitignore @@ -236,3 +236,6 @@ _Pvt_Extensions .fake/ .idea/ + +# Verify.NUnit +*.received.* \ No newline at end of file diff --git a/ObjectPrinting/IPropertySerializer.cs b/ObjectPrinting/IPropertySerializer.cs new file mode 100644 index 00000000..456c5633 --- /dev/null +++ b/ObjectPrinting/IPropertySerializer.cs @@ -0,0 +1,8 @@ +using System; + +namespace ObjectPrinting; + +public interface IPropertySerializer +{ + public PrintingConfig Use(Func converter); +} \ No newline at end of file diff --git a/ObjectPrinting/ITypeSerializer.cs b/ObjectPrinting/ITypeSerializer.cs new file mode 100644 index 00000000..85f24866 --- /dev/null +++ b/ObjectPrinting/ITypeSerializer.cs @@ -0,0 +1,8 @@ +using System; + +namespace ObjectPrinting; + +public interface ITypeSerializer +{ + public PrintingConfig Use(Func converter); +} \ No newline at end of file diff --git a/ObjectPrinting/ObjectExtensions.cs b/ObjectPrinting/ObjectExtensions.cs new file mode 100644 index 00000000..1ac1f44a --- /dev/null +++ b/ObjectPrinting/ObjectExtensions.cs @@ -0,0 +1,17 @@ +using System; + +namespace ObjectPrinting; + +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> configurer) + { + var config = configurer(ObjectPrinter.For()); + return config.PrintToString(obj); + } +} \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinting.csproj b/ObjectPrinting/ObjectPrinting.csproj index c5db392f..ca9fb986 100644 --- a/ObjectPrinting/ObjectPrinting.csproj +++ b/ObjectPrinting/ObjectPrinting.csproj @@ -5,8 +5,10 @@ + + diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index a9e08211..38412eb2 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -1,41 +1,218 @@ using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using System.Text; namespace ObjectPrinting { public class PrintingConfig { + private readonly List _excludedTypes = new(); + private readonly List _excludedProperties = new(); + private readonly Dictionary _typeConverters = new(); + private readonly Dictionary _propertyConverters = new(); + private readonly Dictionary _cultureSpecs = new(); + private readonly Dictionary _stringPropertyLengths = new(); + internal int MaxStringLength { get; set; } = int.MaxValue; + private int MaxRecursionDepth { get; set; } = 16; + public string PrintToString(TOwner obj) { - return PrintToString(obj, 0); + return PrintToString(obj, 0, 0); } - private string PrintToString(object obj, int nestingLevel) + internal void AddCultureSpec(Type type, CultureInfo cultureInfo) { - //TODO apply configurations - if (obj == null) - return "null" + Environment.NewLine; + _cultureSpecs.Add(type, cultureInfo); + } - var finalTypes = new[] - { - typeof(int), typeof(double), typeof(float), typeof(string), - typeof(DateTime), typeof(TimeSpan) - }; - if (finalTypes.Contains(obj.GetType())) - return obj + Environment.NewLine; + internal void AddStringPropertyLength(MemberInfo propertyInfo, int length) + { + _stringPropertyLengths.Add(propertyInfo, length); + } + + public PrintingConfig WithMaxRecursionDepth(int maxRecursionDepth) + { + if (maxRecursionDepth < 0) + throw new ArgumentOutOfRangeException($"{nameof(maxRecursionDepth)} must not be less than 0"); + MaxRecursionDepth = maxRecursionDepth; + return this; + } + + internal void AddTypeConverter(Type type, Func converter) + { + _typeConverters.Add(type, converter); + } + + internal void AddPropertyConverter(Func converter, MemberInfo propertyInfo) + { + _propertyConverters.Add(propertyInfo, converter); + } + + public PrintingConfig ExceptType() + { + _excludedTypes.Add(typeof(T)); + return this; + } + + public PrintingConfig ExceptProperty(Expression> propertyExpression) + { + if (propertyExpression == null) + throw new ArgumentNullException($"{nameof(propertyExpression)} cannot be null"); + + _excludedProperties.Add(GetMemberInfo(propertyExpression)); + return this; + } + + public ITypeSerializer ForType() + { + return new TypeSerializerImpl(this); + } + + public IPropertySerializer ForProperty( + Expression> propertyExpression) + { + if (propertyExpression == null) + throw new ArgumentNullException($"{nameof(propertyExpression)} cannot be null"); + + return new PropertySerializerImpl(this, GetMemberInfo(propertyExpression)); + } + + private static MemberInfo GetMemberInfo(Expression> propertyExpression) + { + if (propertyExpression.Body is MemberExpression memberExpression) + return memberExpression.Member; + + if (propertyExpression.Body is UnaryExpression unaryExpression + && unaryExpression.Operand is MemberExpression unaryMemberExpression) + return unaryMemberExpression.Member; + + throw new ArgumentException("Expression does not refer to a property or field."); + } + + private string PrintToString(object obj, int nestingLevel, int recursionDepth) + { + if (obj == null) + return "null"; + + if (obj is IFormattable formattable + && _cultureSpecs.TryGetValue(formattable.GetType(), out var cultureSpec)) + return $"{formattable.ToString(null, cultureSpec)}"; + + if (obj is string str) + return str.Substring(0, Math.Min(MaxStringLength, str.Length)); + + if (obj.GetType().IsValueType) + return $"{obj}"; + + if (recursionDepth > MaxRecursionDepth) + return "null"; - var identation = new string('\t', nestingLevel + 1); + var indentation = new string('\t', nestingLevel + 1); var sb = new StringBuilder(); var type = obj.GetType(); - sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) + + if (obj is IDictionary dictionary) + return SerializeDictionary(sb, dictionary, nestingLevel, recursionDepth); + + if (obj is IEnumerable enumerable) + return SerializeEnumerable(sb, enumerable, nestingLevel, recursionDepth); + + var bracketIndentation = new string('\t', nestingLevel); + sb.AppendLine($"{type.Name}:"); + sb.AppendLine($"{bracketIndentation}{{"); + var properties = type.GetProperties(); + foreach (var propertyInfo in properties) + { + if (!_excludedProperties.Contains(propertyInfo) && !_excludedTypes.Contains(propertyInfo.PropertyType)) + { + var valueString = GetValueString(propertyInfo, obj, nestingLevel, recursionDepth); + sb.AppendLine($"{indentation}{propertyInfo.Name} = {valueString}"); + } + } + sb.Append($"{bracketIndentation}}}"); + return sb.ToString(); + } + + private string SerializeEnumerable(StringBuilder sb, IEnumerable enumerable, int nestingLevel, int recursionDepth) + { + var bracketIndentation = new string('\t', nestingLevel); + sb.AppendLine($"["); + if (!enumerable.GetEnumerator().MoveNext()) { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); + return "[]"; } + enumerable.GetEnumerator().Reset(); + foreach (var element in enumerable) + { + sb.Append($"{bracketIndentation}\t"); + var valueString = String.Empty; + if (_typeConverters.TryGetValue(element.GetType(), out var typeConverter)) + valueString = + $"{typeConverter.DynamicInvoke(element) as string ?? "null"}"; + else + valueString = PrintToString(element, nestingLevel + 1, recursionDepth + 1); + sb.AppendLine($"{valueString},"); + } + sb.Append($"{bracketIndentation}]"); + return sb.ToString(); + } + + private string SerializeDictionary(StringBuilder sb, IDictionary dictionary, int nestingLevel, int recursionDepth) + { + var bracketIndentation = new string('\t', nestingLevel); + sb.AppendLine($"["); + foreach (DictionaryEntry element in dictionary) + { + var key = element.Key; + var value = element.Value; + + var keyValueIndentation = new string('\t', nestingLevel + 1); + sb.AppendLine($"{bracketIndentation}{{"); + sb.Append($"{keyValueIndentation}key: "); + var keyString = String.Empty; + if (_typeConverters.TryGetValue(key.GetType(), out var typeConverter)) + keyString = + $"{typeConverter.DynamicInvoke(key) as string ?? "null"}"; + else + keyString = PrintToString(key, nestingLevel + 2, recursionDepth + 1); + sb.AppendLine($"{keyString}"); + sb.Append($"{keyValueIndentation}value: "); + var valueString = String.Empty; + if (_typeConverters.TryGetValue(value.GetType(), out typeConverter)) + valueString = + $"{typeConverter.DynamicInvoke(value) as string ?? "null"}"; + else + valueString = PrintToString(value, nestingLevel + 2, recursionDepth + 1); + sb.AppendLine($"{valueString}"); + sb.AppendLine($"{bracketIndentation}}},"); + } + sb.AppendLine($"{bracketIndentation}]"); return sb.ToString(); } + + private string GetValueString(PropertyInfo propertyInfo, object obj, int nestingLevel, int recursionDepth) + { + var propertyValue = propertyInfo.GetValue(obj); + if (propertyValue == null || !TryConvert(propertyInfo, propertyValue, out var valueString)) + valueString = PrintToString(propertyValue, nestingLevel + 1, recursionDepth + 1); + return valueString; + } + + private bool TryConvert(PropertyInfo propertyInfo, object? propertyValue, out string value) + { + value = String.Empty; + if (_propertyConverters.TryGetValue(propertyInfo, out var converter)) + value = $"{converter.DynamicInvoke(propertyValue) as string ?? "null"}"; + else if (propertyValue is string str && _stringPropertyLengths.TryGetValue(propertyInfo, out var length)) + value = $"{str.Substring(0, Math.Min(length, str.Length))}"; + else if (_typeConverters.TryGetValue(propertyInfo.PropertyType, out var typeConverter)) + value = $"{typeConverter.DynamicInvoke(propertyValue) as string ?? "null"}"; + return value != String.Empty; + } } } \ No newline at end of file diff --git a/ObjectPrinting/PropertySerializerExtensions.cs b/ObjectPrinting/PropertySerializerExtensions.cs new file mode 100644 index 00000000..8ae83171 --- /dev/null +++ b/ObjectPrinting/PropertySerializerExtensions.cs @@ -0,0 +1,18 @@ +using System; + +namespace ObjectPrinting; + +public static class PropertySerializerExtensions +{ + public static PrintingConfig UseMaxLength( + this IPropertySerializer serializer, + int maxLength) + { + if (maxLength < 0) + throw new ArgumentOutOfRangeException($"{nameof(maxLength)} cannot be negative"); + var typeSerializer = (PropertySerializerImpl)serializer; + var config = typeSerializer.Config; + config.AddStringPropertyLength(typeSerializer.MemberInfo, maxLength); + return config; + } +} \ No newline at end of file diff --git a/ObjectPrinting/PropertySerializerImpl.cs b/ObjectPrinting/PropertySerializerImpl.cs new file mode 100644 index 00000000..c247950a --- /dev/null +++ b/ObjectPrinting/PropertySerializerImpl.cs @@ -0,0 +1,22 @@ +using System; +using System.Reflection; + +namespace ObjectPrinting; + +internal class PropertySerializerImpl : IPropertySerializer +{ + public PrintingConfig Config { get; } + public readonly MemberInfo MemberInfo; + + internal PropertySerializerImpl(PrintingConfig config, MemberInfo memberInfo) + { + Config = config; + MemberInfo = memberInfo; + } + + public PrintingConfig Use(Func converter) + { + Config.AddPropertyConverter(converter, MemberInfo); + return Config; + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Arrays.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Arrays.verified.txt new file mode 100644 index 00000000..07f3ce1b --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Arrays.verified.txt @@ -0,0 +1,7 @@ +[ + 1, + 2, + 3.14, + 4, + 5, +] diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Dictionaries.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Dictionaries.verified.txt new file mode 100644 index 00000000..4f6f66c9 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Dictionaries.verified.txt @@ -0,0 +1,10 @@ +[ +{ + key: a + value: 1.1 +}, +{ + key: b + value: 2.2 +}, +] diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Lists.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Lists.verified.txt new file mode 100644 index 00000000..7d778fc4 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CollectionSupport_Lists.verified.txt @@ -0,0 +1,4 @@ +[ + Alex, + John, +] diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CultureSpecification.verified.txt new file mode 100644 index 00000000..0506c78e --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CultureSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177.4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CyclicReferenceSupport.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CyclicReferenceSupport.verified.txt new file mode 100644 index 00000000..13d7020f --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.CyclicReferenceSupport.verified.txt @@ -0,0 +1,37 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = null + } + Persons = [] + } + Persons = [] + } + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.ExtensionMethod_ForDefaultSerialization.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.ExtensionMethod_ForDefaultSerialization.verified.txt new file mode 100644 index 00000000..bb4f3210 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.ExtensionMethod_ForDefaultSerialization.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.ExtensionMethod_WithConfigurationSupport.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.ExtensionMethod_WithConfigurationSupport.verified.txt new file mode 100644 index 00000000..05b70cd8 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.ExtensionMethod_WithConfigurationSupport.verified.txt @@ -0,0 +1,9 @@ +Person: +{ + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.PropertyExclusion.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.PropertyExclusion.verified.txt new file mode 100644 index 00000000..05b70cd8 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.PropertyExclusion.verified.txt @@ -0,0 +1,9 @@ +Person: +{ + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.PropertySerializationSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.PropertySerializationSpecification.verified.txt new file mode 100644 index 00000000..39df8a01 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.PropertySerializationSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = John + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.StringPropertyTrimming.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.StringPropertyTrimming.verified.txt new file mode 100644 index 00000000..5fbca773 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.StringPropertyTrimming.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Sm + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.StringTrimming.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.StringTrimming.verified.txt new file mode 100644 index 00000000..4892b622 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.StringTrimming.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Al + Surname = Sm + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.TypeExclusion.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.TypeExclusion.verified.txt new file mode 100644 index 00000000..aec1d7db --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.TypeExclusion.verified.txt @@ -0,0 +1,8 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.TypeSerializationSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.TypeSerializationSpecification.verified.txt new file mode 100644 index 00000000..8b6b1ba3 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.TypeSerializationSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = ALEX + Surname = SMITH + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs index 4c8b2445..1bd407b6 100644 --- a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs +++ b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs @@ -1,27 +1,193 @@ -using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; -namespace ObjectPrinting.Tests +namespace ObjectPrinting.Tests; + +[TestFixture] +public class ObjectPrinterAcceptanceTests { - [TestFixture] - public class ObjectPrinterAcceptanceTests + private Person _person; + private PrintingConfig _config; + + [SetUp] + public void SetUp() { - [Test] - public void Demo() + _person = new Person { - 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. ...с конфигурированием - } + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _config = ObjectPrinter.For(); + } + + [Test] + [Description("Возможность исключения из сериализации свойств определенного типа")] + public Task TypeExclusion() + { + var str = _config + .ExceptType() + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Возможность указать альтернативный способ сериализации для определенного типа")] + public Task TypeSerializationSpecification() + { + var str = _config + .ForType() + .Use(o => o.ToUpper()) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Возможность для числовых типов указать культуру")] + public Task CultureSpecification() + { + var str = _config + .ForType() + .UseCulture(CultureInfo.InvariantCulture) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Возможность настройки сериализации конкретного свойства")] + public Task PropertySerializationSpecification() + { + _person.OtherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + + var str = _config + .ForProperty(x => x.OtherPerson!) + .Use(o => o.Name) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Возможность обрезания строк")] + public Task StringTrimming() + { + var str = _config + .ForType() + .UseMaxLength(2) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Возможность обрезания конкретных строковых полей")] + public Task StringPropertyTrimming() + { + var str = _config + .ForProperty(x => x.Surname) + .UseMaxLength(2) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Возможность исключения из сериализации конкретного свойства/поля")] + public Task PropertyExclusion() + { + var str = _config + .ExceptProperty(x => x.Id) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Обработка циклических ссылок между объектами")] + public Task CyclicReferenceSupport() + { + _person.OtherPerson = _person; + + var str = _config + .WithMaxRecursionDepth(3) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + [Description("Метод-расширение для сериализации по умолчанию")] + public Task ExtensionMethod_ForDefaultSerialization() + { + var str = _person.PrintToString(); + + return Verifier.Verify(str); + } + + [Test] + [Description("Метод-расширение, позволяющий проводить настройку сериализации")] + public Task ExtensionMethod_WithConfigurationSupport() + { + var str = _person.PrintToString( + config => config.ExceptProperty(x => x.Id)); + + return Verifier.Verify(str); + } + + [Test] + [Description("Сериализация массивов")] + public Task CollectionSupport_Arrays() + { + var arr = new double[] {1, 2, 3.14, 4, 5}; + + var str = arr.PrintToString( + config => config + .ForType() + .UseCulture(CultureInfo.InvariantCulture)); + + return Verifier.Verify(str); + } + + [Test] + [Description("Сериализация списков")] + public Task CollectionSupport_Lists() + { + var list = new List + { + _person, + new Person { Id = new Guid(), Name = "John", Surname = "Doe" } + }; + + var str = list.PrintToString( + config => config + .ForType() + .Use(o => o.Name)); + + return Verifier.Verify(str); + } + + [Test] + [Description("Сериализация словарей")] + public Task CollectionSupport_Dictionaries() + { + var dictionary = new Dictionary + { + { "a", 1.1 }, + { "b", 2.2 } + }; + + var str = dictionary.PrintToString( + config => config + .ForType() + .UseCulture(CultureInfo.InvariantCulture)); + + return Verifier.Verify(str); } } \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ArrayOfNonValueType.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ArrayOfNonValueType.verified.txt new file mode 100644 index 00000000..ae62ca7b --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ArrayOfNonValueType.verified.txt @@ -0,0 +1,22 @@ +[ + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + }, + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, +] \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryOfArrays.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryOfArrays.verified.txt new file mode 100644 index 00000000..e5dbf526 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryOfArrays.verified.txt @@ -0,0 +1,42 @@ +[ +{ + key: one + value: [ + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + }, + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, + ] +}, +{ + key: two + value: [ + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Steve + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, + ] +}, +] diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryOfNonValueType.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryOfNonValueType.verified.txt new file mode 100644 index 00000000..e94fd217 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryOfNonValueType.verified.txt @@ -0,0 +1,41 @@ +[ +{ + key: John + value: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } +}, +{ + key: Alex + value: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + } +}, +{ + key: Steve + value: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Steve + Surname = Smith + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } +}, +] diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryWithNonValueTypeKey.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryWithNonValueTypeKey.verified.txt new file mode 100644 index 00000000..18dbc286 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.DictionaryWithNonValueTypeKey.verified.txt @@ -0,0 +1,46 @@ +[ +{ + key: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + } + value: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } +}, +{ + key: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } + value: Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Steve + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } +}, +] diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ListOfArrays.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ListOfArrays.verified.txt new file mode 100644 index 00000000..0751e43d --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ListOfArrays.verified.txt @@ -0,0 +1,46 @@ +[ + [ + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + }, + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, + ], + [ + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Veronica + Surname = null + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Steve + Surname = null + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, + ], +] \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ListOfNonValueType.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ListOfNonValueType.verified.txt new file mode 100644 index 00000000..ae62ca7b --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.ListOfNonValueType.verified.txt @@ -0,0 +1,22 @@ +[ + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + }, + Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, +] \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.cs b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.cs new file mode 100644 index 00000000..24e24d02 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CollectionsSerializationTests/CollectionsSerializationTests.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_CollectionsSerializationTests; + +[TestFixture] +public class CollectionsSerializationTests +{ + private Person _person; + private Person _otherPerson; + private Person[] _persons; + private List _personList; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _otherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + + _persons = new Person[] { _person, _otherPerson }; + + _personList = new List(); + _personList.Add(_person); + _personList.Add(_otherPerson); + } + + [Test] + public Task ArrayOfNonValueType() + { + var str = ObjectPrinter.For() + .PrintToString(_persons); + + return Verifier.Verify(str); + } + + [Test] + public Task ListOfNonValueType() + { + var str = ObjectPrinter.For>() + .PrintToString(_personList); + + return Verifier.Verify(str); + } + + [Test] + public Task ListOfArrays() + { + var list = new List(); + list.Add(new Person[] { _person, _otherPerson }); + list.Add(new Person[] { new Person{ Name = "Veronica" }, new Person { Name = "Steve" } }); + + var str = ObjectPrinter.For>() + .PrintToString(list); + + return Verifier.Verify(str); + } + + [Test] + public Task DictionaryOfNonValueType() + { + var dictionary = new Dictionary(); + dictionary.Add("John", _otherPerson); + dictionary.Add("Alex", _person); + dictionary.Add("Steve", new Person { Name = "Steve", Surname = "Smith" }); + + var str = ObjectPrinter.For>() + .PrintToString(dictionary); + + return Verifier.Verify(str); + } + + [Test] + public Task DictionaryOfArrays() + { + var dictionary = new Dictionary(); + dictionary.Add("one", _persons); + dictionary.Add("two", new Person[] { new Person { Name = "Steve", Surname = "Doe" } }); + + var str = ObjectPrinter.For>() + .PrintToString(dictionary); + + return Verifier.Verify(str); + } + + [Test] + public Task DictionaryWithNonValueTypeKey() + { + var dictionary = new Dictionary(); + dictionary.Add(_person, _otherPerson); + dictionary.Add(_otherPerson, new Person { Name = "Steve", Surname = "Doe" }); + + var str = ObjectPrinter.For>() + .PrintToString(dictionary); + + return Verifier.Verify(str); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.BasicCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.BasicCultureSpecification.verified.txt new file mode 100644 index 00000000..0506c78e --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.BasicCultureSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177.4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.ComplexCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.ComplexCultureSpecification.verified.txt new file mode 100644 index 00000000..58c28c57 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.ComplexCultureSpecification.verified.txt @@ -0,0 +1 @@ +09/01/2021 00:00:00 \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DateCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DateCultureSpecification.verified.txt new file mode 100644 index 00000000..58c28c57 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DateCultureSpecification.verified.txt @@ -0,0 +1 @@ +09/01/2021 00:00:00 \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultCultureSpecification.verified.txt new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultCultureSpecification.verified.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultDateCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultDateCultureSpecification.verified.txt new file mode 100644 index 00000000..195ace8b --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultDateCultureSpecification.verified.txt @@ -0,0 +1 @@ +01.09.2021 0:00:00 \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultDoubleCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultDoubleCultureSpecification.verified.txt new file mode 100644 index 00000000..bb4f3210 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultDoubleCultureSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultFloatCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultFloatCultureSpecification.verified.txt new file mode 100644 index 00000000..7b53f087 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DefaultFloatCultureSpecification.verified.txt @@ -0,0 +1 @@ +3,14 \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DoubleCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DoubleCultureSpecification.verified.txt new file mode 100644 index 00000000..0506c78e --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.DoubleCultureSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177.4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.FloatCultureSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.FloatCultureSpecification.verified.txt new file mode 100644 index 00000000..cee8eed8 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.FloatCultureSpecification.verified.txt @@ -0,0 +1 @@ +3.14 \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.cs b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.cs new file mode 100644 index 00000000..7d3b24d0 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_CultureSpecificationTests/CultureSpecificationTests.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_CultureSpecificationTests; + +[TestFixture] +public class CultureSpecificationTests +{ + private Person _person; + private PrintingConfig _personConfig; + private DateTime _dateTime; + private float _float; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + + _personConfig = ObjectPrinter.For(); + + _dateTime = DateTime.Parse("2021-09-01"); + _float = 3.14f; + } + + [Test] + public Task DoubleCultureSpecification() + { + var str = _personConfig + .ForType() + .UseCulture(CultureInfo.InvariantCulture) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task DefaultDoubleCultureSpecification() + { + var str = _personConfig + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task FloatCultureSpecification() + { + var str = ObjectPrinter.For() + .ForType() + .UseCulture(CultureInfo.InvariantCulture) + .PrintToString(_float); + + return Verifier.Verify(str); + } + + [Test] + public Task DefaultFloatCultureSpecification() + { + var str = ObjectPrinter.For() + .PrintToString(_float); + + return Verifier.Verify(str); + } + + [Test] + public Task DateCultureSpecification() + { + var str = ObjectPrinter.For() + .ForType() + .UseCulture(CultureInfo.InvariantCulture) + .PrintToString(_dateTime); + + return Verifier.Verify(str); + } + + [Test] + public Task DefaultDateCultureSpecification() + { + var str = ObjectPrinter.For() + .PrintToString(_dateTime); + + return Verifier.Verify(str); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.ExcludesTypesOfFieldsOfInnerObjects.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.ExcludesTypesOfFieldsOfInnerObjects.verified.txt new file mode 100644 index 00000000..c74cedf5 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.ExcludesTypesOfFieldsOfInnerObjects.verified.txt @@ -0,0 +1,26 @@ +PersonDatabase: +{ + People = [ + Person: + { + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + }, + Person: + { + Name = John + Surname = Doe + Height = 0 + Age = 0 + }, + ] + Owner = Person: + { + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.MultipleTypeExclusion.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.MultipleTypeExclusion.verified.txt new file mode 100644 index 00000000..735f1407 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.MultipleTypeExclusion.verified.txt @@ -0,0 +1,7 @@ +Person: +{ + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.cs b/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.cs new file mode 100644 index 00000000..0cb7b055 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertyExclusionTests/PropertyExclusionTests.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_PropertyExclusionTests; + +[TestFixture] +public class PropertyExclusionTests +{ + private Person _person; + private Person _otherPerson; + private PersonDatabase _personDatabase; + private PrintingConfig _personConfig; + private PrintingConfig _personDatabaseConfig; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _otherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + + _personDatabase = new PersonDatabase(); + _personDatabase.People.Add(_person); + _personDatabase.People.Add(_otherPerson); + _personDatabase.Owner = _person; + + _personConfig = ObjectPrinter.For(); + _personDatabaseConfig = ObjectPrinter.For(); + } + + [Test] + public Task MultipleTypeExclusion() + { + var str = _personConfig + .ExceptProperty(x => x.Id) + .ExceptProperty(x => x.OtherPerson!) + .ExceptProperty(x => x.Persons) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task ExcludesTypesOfFieldsOfInnerObjects() + { + var str = _personDatabaseConfig + .ExceptProperty(x => x.Owner.Id) + .ExceptProperty(x => x.Owner.OtherPerson!) + .ExceptProperty(x => x.Owner.Persons) + .PrintToString(_personDatabase); + + return Verifier.Verify(str); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.BasicFieldSerializationSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.BasicFieldSerializationSpecification.verified.txt new file mode 100644 index 00000000..d3018130 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.BasicFieldSerializationSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = ALEX + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.BasicPropertySerializationSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.BasicPropertySerializationSpecification.verified.txt new file mode 100644 index 00000000..d3018130 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.BasicPropertySerializationSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = ALEX + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.InnerPropertySerializationSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.InnerPropertySerializationSpecification.verified.txt new file mode 100644 index 00000000..21a6328e --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.InnerPropertySerializationSpecification.verified.txt @@ -0,0 +1,19 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = ALEX + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = JOHN + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.MultiplePropertySerializationSpecification.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.MultiplePropertySerializationSpecification.verified.txt new file mode 100644 index 00000000..b1b18c63 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.MultiplePropertySerializationSpecification.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = ALEX + Surname = smith + Height = 177,4 + Age = 19 + OtherPerson = 00000000-0000-0000-0000-000000000000 + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.cs b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.cs new file mode 100644 index 00000000..0a3b01bc --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_PropertySerializationTests/PropertySerializationTests.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_PropertySerializationTests; + +[TestFixture] +public class PropertySerializationTests +{ + private Person _person; + private Person _otherPerson; + private PrintingConfig _personConfig; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _otherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + + _personConfig = ObjectPrinter.For(); + } + + [Test] + public Task BasicPropertySerializationSpecification() + { + var str = _personConfig + .ForProperty(x => x.Name) + .Use(o => o.ToUpper()) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task MultiplePropertySerializationSpecification() + { + _person.OtherPerson = _otherPerson; + + var str = _personConfig + .ForProperty(x => x.Name) + .Use(o => o.ToUpper()) + .ForProperty(x => x.Surname) + .Use(o => o.ToLower()) + .ForProperty(x => x.OtherPerson) + .Use(o => o.Id.ToString()) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task InnerPropertySerializationSpecification() + { + _person.OtherPerson = _otherPerson; + + var str = _personConfig + .ForProperty(x => x.Name) + .Use(o => o.ToUpper()) + .PrintToString(_person); + + return Verifier.Verify(str); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesAreTrimmedCorrectly.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesAreTrimmedCorrectly.verified.txt new file mode 100644 index 00000000..121a2cc7 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesAreTrimmedCorrectly.verified.txt @@ -0,0 +1,19 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Al + Surname = Sm + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = Jo + Surname = Do + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesBecomeEmptyWhenLengthIsZero.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesBecomeEmptyWhenLengthIsZero.verified.txt new file mode 100644 index 00000000..ae530dd4 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesBecomeEmptyWhenLengthIsZero.verified.txt @@ -0,0 +1,19 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = + Surname = + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = + Surname = + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesDontChangeIfLengthIsBigger.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesDontChangeIfLengthIsBigger.verified.txt new file mode 100644 index 00000000..b900795c --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesDontChangeIfLengthIsBigger.verified.txt @@ -0,0 +1,19 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesDontChangeWithDefaultSettings.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesDontChangeWithDefaultSettings.verified.txt new file mode 100644 index 00000000..796024bb --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.StringPropertiesDontChangeWithDefaultSettings.verified.txt @@ -0,0 +1,19 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = Person: + { + Id = 00000000-0000-0000-0000-000000000000 + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + } + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.cs b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.cs new file mode 100644 index 00000000..b9bad982 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_StringTrimmingTests/StringTrimmingTests.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using FluentAssertions; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_StringTrimmingTests; + +[TestFixture] +public class StringTrimmingTests +{ + private Person _person; + private Person _otherPerson; + private PrintingConfig _personConfig; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _otherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + _person.OtherPerson = _otherPerson; + + _personConfig = ObjectPrinter.For(); + } + + [Test] + public Task StringPropertiesAreTrimmedCorrectly() + { + var str = _personConfig + .ForType() + .UseMaxLength(2) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task StringPropertiesBecomeEmptyWhenLengthIsZero() + { + var str = _personConfig + .ForType() + .UseMaxLength(0) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task StringPropertiesDontChangeIfLengthIsBigger() + { + var str = _personConfig + .ForType() + .UseMaxLength(15) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task StringPropertiesDontChangeWithDefaultSettings() + { + _person.Name = new string('a', 100); + + var str = _personConfig + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public void UseMaxLengthThrowsWhenArgumentIsLessThanZero() + { + _person.Name = new string('a', 100); + + Action act = () => _personConfig + .ForType() + .UseMaxLength(-1); + + act.Should().Throw(); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.DoesNotExcludeAnythingIfSpecifiedTypeIsNotPresent.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.DoesNotExcludeAnythingIfSpecifiedTypeIsNotPresent.verified.txt new file mode 100644 index 00000000..bb4f3210 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.DoesNotExcludeAnythingIfSpecifiedTypeIsNotPresent.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.ExcludesTypesOfFieldsOfInnerObjects.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.ExcludesTypesOfFieldsOfInnerObjects.verified.txt new file mode 100644 index 00000000..7a15861a --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.ExcludesTypesOfFieldsOfInnerObjects.verified.txt @@ -0,0 +1,32 @@ +PersonDatabase: +{ + People = [ + Person: + { + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + }, + Person: + { + Name = John + Surname = Doe + Height = 0 + Age = 0 + OtherPerson = null + Persons = null + }, + ] + Owner = Person: + { + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.MultipleTypeExclusion.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.MultipleTypeExclusion.verified.txt new file mode 100644 index 00000000..735f1407 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.MultipleTypeExclusion.verified.txt @@ -0,0 +1,7 @@ +Person: +{ + Name = Alex + Surname = Smith + Height = 177,4 + Age = 19 +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.cs b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.cs new file mode 100644 index 00000000..17dc1421 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeExclusionTests/TypeExclusionTests.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_TypeExclusionTests; + +[TestFixture] +public class TypeExclusionTests +{ + private Person _person; + private Person _otherPerson; + private PersonDatabase _personDatabase; + private PrintingConfig _personConfig; + private PrintingConfig _personDatabaseConfig; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _otherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + + _personDatabase = new PersonDatabase(); + _personDatabase.People.Add(_person); + _personDatabase.People.Add(_otherPerson); + _personDatabase.Owner = _person; + + _personConfig = ObjectPrinter.For(); + _personDatabaseConfig = ObjectPrinter.For(); + } + + [Test] + public Task MultipleTypeExclusion() + { + var str = _personConfig + .ExceptType() + .ExceptType() + .ExceptType>() + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task DoesNotExcludeAnythingIfSpecifiedTypeIsNotPresent() + { + var str = _personConfig + .ExceptType() + .ExceptType() + .ExceptType() + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task ExcludesTypesOfFieldsOfInnerObjects() + { + var str = _personDatabaseConfig + .ExceptType() + .PrintToString(_personDatabase); + + return Verifier.Verify(str); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.BasicTypeSerializationSpecificationTest.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.BasicTypeSerializationSpecificationTest.verified.txt new file mode 100644 index 00000000..8b6b1ba3 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.BasicTypeSerializationSpecificationTest.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000000-0000-0000-0000-000000000000 + Name = ALEX + Surname = SMITH + Height = 177,4 + Age = 19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.MultipleTypeSerializationSpecificationTest.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.MultipleTypeSerializationSpecificationTest.verified.txt new file mode 100644 index 00000000..cddb5c64 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.MultipleTypeSerializationSpecificationTest.verified.txt @@ -0,0 +1,10 @@ +Person: +{ + Id = 00000 + Name = ALEX + Surname = SMITH + Height = 177,4 + Age = -19 + OtherPerson = null + Persons = [] +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.TypeSerializationSpecificationForComplexObjects.verified.txt b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.TypeSerializationSpecificationForComplexObjects.verified.txt new file mode 100644 index 00000000..be07a3c3 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.TypeSerializationSpecificationForComplexObjects.verified.txt @@ -0,0 +1,8 @@ +PersonDatabase: +{ + People = [ + Alex, + John, + ] + Owner = Alex +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.cs b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.cs new file mode 100644 index 00000000..07a98a48 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinter_TypeSerializationTests/TypeSerializationTests.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +namespace ObjectPrinting.Tests.ObjectPrinter_TypeSerializationTests; + +[TestFixture] +public class TypeSerializationTests +{ + private Person _person; + private Person _otherPerson; + private PersonDatabase _personDatabase; + private PrintingConfig _personConfig; + private PrintingConfig _personDatabaseConfig; + + [SetUp] + public void SetUp() + { + _person = new Person + { + Id = new Guid(), Name = "Alex", Surname = "Smith", + Age = 19, Height = 177.4, Persons = new List() + }; + _otherPerson = new Person { Id = new Guid(), Name = "John", Surname = "Doe" }; + + _personDatabase = new PersonDatabase(); + _personDatabase.People.Add(_person); + _personDatabase.People.Add(_otherPerson); + _personDatabase.Owner = _person; + + _personConfig = ObjectPrinter.For(); + _personDatabaseConfig = ObjectPrinter.For(); + } + + [Test] + public Task BasicTypeSerializationSpecificationTest() + { + var str = _personConfig + .ForType() + .Use(o => o.ToUpper()) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task MultipleTypeSerializationSpecificationTest() + { + var str = _personConfig + .ForType() + .Use(o => o.ToUpper()) + .ForType() + .Use(o => o.ToString().Substring(0, 5)) + .ForType() + .Use(o => (-o).ToString()) + .PrintToString(_person); + + return Verifier.Verify(str); + } + + [Test] + public Task TypeSerializationSpecificationForComplexObjects() + { + var str = _personDatabaseConfig + .ForType() + .Use(o => o.Name) + .PrintToString(_personDatabase); + + return Verifier.Verify(str); + } +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/Person.cs b/ObjectPrinting/Tests/Person.cs index f9555955..0f37de62 100644 --- a/ObjectPrinting/Tests/Person.cs +++ b/ObjectPrinting/Tests/Person.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace ObjectPrinting.Tests { @@ -6,7 +7,16 @@ public class Person { public Guid Id { get; set; } public string Name { get; set; } + public string Surname { get; set; } public double Height { get; set; } public int Age { get; set; } + + public Person? OtherPerson { get; set; } + public List Persons { get; set; } + + public override int GetHashCode() + { + return HashCode.Combine(Id, Name, Surname, Height, Age); + } } } \ No newline at end of file diff --git a/ObjectPrinting/Tests/PersonDatabase.cs b/ObjectPrinting/Tests/PersonDatabase.cs new file mode 100644 index 00000000..06f586dd --- /dev/null +++ b/ObjectPrinting/Tests/PersonDatabase.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace ObjectPrinting.Tests; + +public class PersonDatabase +{ + public List People { get; set; } = new List(); + public Person Owner { get; set; } +} \ No newline at end of file diff --git a/ObjectPrinting/TypeSerializerExtensions.cs b/ObjectPrinting/TypeSerializerExtensions.cs new file mode 100644 index 00000000..85417610 --- /dev/null +++ b/ObjectPrinting/TypeSerializerExtensions.cs @@ -0,0 +1,36 @@ +using System; +using System.Globalization; + +namespace ObjectPrinting; + +public static class TypeSerializerExtensions +{ + private static PrintingConfig GetConfig(ITypeSerializer typeSerializer) + { + return ((TypeSerializerImpl)typeSerializer).Config; + } + + public static PrintingConfig UseCulture( + this ITypeSerializer typeSerializer, + CultureInfo cultureInfo) + where TParam : IFormattable + { + if (cultureInfo == null) + throw new ArgumentNullException($"{nameof(cultureInfo)} cannot be null"); + var config = GetConfig(typeSerializer); + config.AddCultureSpec(typeof(TParam), cultureInfo); + return config; + } + + public static PrintingConfig UseMaxLength( + this ITypeSerializer typeSerializer, + int maxLength) + { + if (maxLength < 0) + throw new ArgumentOutOfRangeException($"{nameof(maxLength)} cannot be negative"); + + var config = GetConfig(typeSerializer); + config.MaxStringLength = maxLength; + return config; + } +} \ No newline at end of file diff --git a/ObjectPrinting/TypeSerializerImpl.cs b/ObjectPrinting/TypeSerializerImpl.cs new file mode 100644 index 00000000..88a91eda --- /dev/null +++ b/ObjectPrinting/TypeSerializerImpl.cs @@ -0,0 +1,21 @@ +using System; + +namespace ObjectPrinting; + +internal class TypeSerializerImpl : ITypeSerializer +{ + public PrintingConfig Config { get; } + + internal TypeSerializerImpl(PrintingConfig config) + { + Config = config; + } + + public PrintingConfig Use(Func converter) + { + if (converter == null) + throw new ArgumentNullException($"{nameof(converter)} cannot be null"); + Config.AddTypeConverter(typeof(TParam), converter); + return Config; + } +} \ No newline at end of file