From 964bbaab8e72ac177b98327456919302e5d27103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 8 Oct 2025 09:30:13 +0200 Subject: [PATCH] feat: customize the `MaximumStringLength` --- .../AwexpectCustomization.Formatting.cs | 14 +++++++++++ .../Formatting/ValueFormatters.String.cs | 7 +++--- .../StringEqualityOptions.ExactMatchType.cs | 19 +++++++++----- .../StringEqualityOptions.PrefixMatchType.cs | 10 +++++--- .../StringEqualityOptions.SuffixMatchType.cs | 13 +++++++--- .../Expected/aweXpect.Core_net8.0.txt | 2 ++ .../Expected/aweXpect.Core_netstandard2.0.txt | 2 ++ .../Customization/CustomizeFormattingTests.cs | 25 ++++++++++++++++--- 8 files changed, 73 insertions(+), 19 deletions(-) diff --git a/Source/aweXpect.Core/Customization/AwexpectCustomization.Formatting.cs b/Source/aweXpect.Core/Customization/AwexpectCustomization.Formatting.cs index 010f201f9..235c2a940 100644 --- a/Source/aweXpect.Core/Customization/AwexpectCustomization.Formatting.cs +++ b/Source/aweXpect.Core/Customization/AwexpectCustomization.Formatting.cs @@ -38,11 +38,20 @@ internal FormattingCustomization(IAwexpectCustomization awexpectCustomization) { MinimumNumberOfCharactersAfterStringDifference = v, })); + MaximumStringLength = new CustomizationValue( + () => Get().MaximumStringLength, + v => Update(p => p with + { + MaximumStringLength = v, + })); } /// public ICustomizationValueSetter MaximumNumberOfCollectionItems { get; } + /// + public ICustomizationValueSetter MaximumStringLength { get; } + /// public ICustomizationValueSetter MinimumNumberOfCharactersAfterStringDifference { get; } @@ -65,6 +74,11 @@ public record FormattingCustomizationValue /// The maximum number of displayed items in a collection. /// public int MaximumNumberOfCollectionItems { get; init; } = 10; + + /// + /// The maximum length of a before it gets truncated. + /// + public int MaximumStringLength { get; init; } = 100; /// /// The minimum number of characters included after the first mismatch in the string difference. diff --git a/Source/aweXpect.Core/Formatting/ValueFormatters.String.cs b/Source/aweXpect.Core/Formatting/ValueFormatters.String.cs index 582b69157..38b250ae8 100644 --- a/Source/aweXpect.Core/Formatting/ValueFormatters.String.cs +++ b/Source/aweXpect.Core/Formatting/ValueFormatters.String.cs @@ -1,5 +1,6 @@ using System.Text; using aweXpect.Core.Helpers; +using aweXpect.Customization; namespace aweXpect.Formatting; @@ -22,9 +23,9 @@ public static string Format( return (options.UseLineBreaks, options.IncludeType) switch { (true, true) => $"string \"{value}\"", - (false, true) => $"string \"{value.DisplayWhitespace().TruncateWithEllipsis(100)}\"", + (false, true) => $"string \"{value.DisplayWhitespace().TruncateWithEllipsis(Customize.aweXpect.Formatting().MaximumStringLength.Get())}\"", (true, false) => $"\"{value}\"", - (false, false) => $"\"{value.DisplayWhitespace().TruncateWithEllipsis(100)}\"", + (false, false) => $"\"{value.DisplayWhitespace().TruncateWithEllipsis(Customize.aweXpect.Formatting().MaximumStringLength.Get())}\"", }; } @@ -53,7 +54,7 @@ public static void Format( stringBuilder.Append('\"'); if (!options.UseLineBreaks) { - stringBuilder.Append(value.DisplayWhitespace().TruncateWithEllipsis(100)); + stringBuilder.Append(value.DisplayWhitespace().TruncateWithEllipsis(Customize.aweXpect.Formatting().MaximumStringLength.Get())); } else { diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs index 097b437b5..1af81a3c0 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using aweXpect.Core; using aweXpect.Core.Helpers; +using aweXpect.Customization; namespace aweXpect.Options; @@ -59,38 +60,44 @@ public string GetExtendedFailure(string it, string? actual, string? expected, int indexOfFirstMismatch = stringDifference.IndexOfFirstMismatch(StringDifference.MatchType.Equality); if (indexOfFirstMismatch == 0 && comparer.Equals(actual.TrimStart(), expected)) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which has unexpected whitespace (\"{actual.Substring(0, GetIndexOfFirstMatch(actual, expected, comparer)).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the beginning)"; + $"{prefix} which has unexpected whitespace (\"{actual.Substring(0, GetIndexOfFirstMatch(actual, expected, comparer)).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the beginning)"; } if (indexOfFirstMismatch == 0 && comparer.Equals(actual, expected.TrimStart())) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which misses some whitespace (\"{expected.Substring(0, GetIndexOfFirstMatch(expected, actual, comparer)).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the beginning)"; + $"{prefix} which misses some whitespace (\"{expected.Substring(0, GetIndexOfFirstMatch(expected, actual, comparer)).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the beginning)"; } if (indexOfFirstMismatch == minCommonLength && comparer.Equals(actual.TrimEnd(), expected)) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which has unexpected whitespace (\"{actual.Substring(indexOfFirstMismatch).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the end)"; + $"{prefix} which has unexpected whitespace (\"{actual.Substring(indexOfFirstMismatch).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the end)"; } if (indexOfFirstMismatch == minCommonLength && comparer.Equals(actual, expected.TrimEnd())) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which misses some whitespace (\"{expected.Substring(indexOfFirstMismatch).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the end)"; + $"{prefix} which misses some whitespace (\"{expected.Substring(indexOfFirstMismatch).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the end)"; } if (actual.Length < expected.Length && indexOfFirstMismatch == actual.Length) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} with a length of {actual.Length} which is shorter than the expected length of {expected.Length} and misses:{Environment.NewLine} \"{expected.Substring(actual.Length).TruncateWithEllipsis(100)}\""; + $"{prefix} with a length of {actual.Length} which is shorter than the expected length of {expected.Length} and misses:{Environment.NewLine} \"{expected.Substring(actual.Length).TruncateWithEllipsis(maxStringLength)}\""; } if (actual.Length > expected.Length && indexOfFirstMismatch == expected.Length) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} with a length of {actual.Length} which is longer than the expected length of {expected.Length} and has superfluous:{Environment.NewLine} \"{actual.Substring(expected.Length).TruncateWithEllipsis(100)}\""; + $"{prefix} with a length of {actual.Length} which is longer than the expected length of {expected.Length} and has superfluous:{Environment.NewLine} \"{actual.Substring(expected.Length).TruncateWithEllipsis(maxStringLength)}\""; } return $"{prefix} which {stringDifference}"; diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs index 265f2021a..4dfffa3a8 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using aweXpect.Core; using aweXpect.Core.Helpers; +using aweXpect.Customization; namespace aweXpect.Options; @@ -63,21 +64,24 @@ public string GetExtendedFailure(string it, string? actual, string? expected, int commonLength = Math.Min(trimmedActual.Length, expected.Length); if (comparer.Equals(trimmedActual[..commonLength], expected[..commonLength])) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which has unexpected whitespace (\"{actual.Substring(0, GetIndexOfFirstMatch(actual, expected, comparer)).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the beginning)"; + $"{prefix} which has unexpected whitespace (\"{actual.Substring(0, GetIndexOfFirstMatch(actual, expected, comparer)).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the beginning)"; } } if (indexOfFirstMismatch == 0 && comparer.Equals(actual, expected.TrimStart())) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which misses some whitespace (\"{expected.Substring(0, GetIndexOfFirstMatch(expected, actual, comparer)).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the beginning)"; + $"{prefix} which misses some whitespace (\"{expected.Substring(0, GetIndexOfFirstMatch(expected, actual, comparer)).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the beginning)"; } if (actual.Length < expected.Length && indexOfFirstMismatch == actual.Length) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} with a length of {actual.Length} which is shorter than the expected length of {expected.Length} and misses:{Environment.NewLine} \"{expected.Substring(actual.Length).TruncateWithEllipsis(100)}\""; + $"{prefix} with a length of {actual.Length} which is shorter than the expected length of {expected.Length} and misses:{Environment.NewLine} \"{expected.Substring(actual.Length).TruncateWithEllipsis(maxStringLength)}\""; } return $"{prefix} which {stringDifference}"; diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs index 121089364..ded5b36ea 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using aweXpect.Core; using aweXpect.Core.Helpers; +using aweXpect.Customization; namespace aweXpect.Options; @@ -60,8 +61,9 @@ public string GetExtendedFailure(string it, string? actual, string? expected, int indexOfFirstMismatch = stringDifference.IndexOfFirstMismatch(StringDifference.MatchType.Suffix); if (indexOfFirstMismatch == 0 && comparer.Equals(actual, expected.TrimStart())) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which misses some whitespace (\"{expected.Substring(0, GetIndexOfFirstMatch(expected, actual, comparer)).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the beginning)"; + $"{prefix} which misses some whitespace (\"{expected.Substring(0, GetIndexOfFirstMatch(expected, actual, comparer)).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the beginning)"; } if (indexOfFirstMismatch == actual.Length) @@ -70,21 +72,24 @@ public string GetExtendedFailure(string it, string? actual, string? expected, int commonLength = Math.Min(trimmedActual.Length, expected.Length); if (comparer.Equals(trimmedActual[^commonLength..], expected[^commonLength..])) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which has unexpected whitespace (\"{actual.Substring(trimmedActual.Length).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the end)"; + $"{prefix} which has unexpected whitespace (\"{actual.Substring(trimmedActual.Length).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the end)"; } } if (indexOfFirstMismatch == minCommonLength && comparer.Equals(actual, expected.TrimEnd())) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} which misses some whitespace (\"{expected.Substring(indexOfFirstMismatch).DisplayWhitespace().TruncateWithEllipsis(100)}\" at the end)"; + $"{prefix} which misses some whitespace (\"{expected.Substring(indexOfFirstMismatch).DisplayWhitespace().TruncateWithEllipsis(maxStringLength)}\" at the end)"; } if (actual.Length < expected.Length && indexOfFirstMismatch == actual.Length) { + int maxStringLength = Customize.aweXpect.Formatting().MaximumStringLength.Get(); return - $"{prefix} with a length of {actual.Length} which is shorter than the expected length of {expected.Length} and misses:{Environment.NewLine} \"{expected.Substring(actual.Length).TruncateWithEllipsis(100)}\""; + $"{prefix} with a length of {actual.Length} which is shorter than the expected length of {expected.Length} and misses:{Environment.NewLine} \"{expected.Substring(actual.Length).TruncateWithEllipsis(maxStringLength)}\""; } return $"{prefix} which {stringDifference}"; diff --git a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt index 42818f14b..a18e8c9e5 100644 --- a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt +++ b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt @@ -402,6 +402,7 @@ namespace aweXpect.Customization public class FormattingCustomization : aweXpect.Customization.ICustomizationValueUpdater { public aweXpect.Customization.ICustomizationValueSetter MaximumNumberOfCollectionItems { get; } + public aweXpect.Customization.ICustomizationValueSetter MaximumStringLength { get; } public aweXpect.Customization.ICustomizationValueSetter MinimumNumberOfCharactersAfterStringDifference { get; } public aweXpect.Customization.AwexpectCustomization.FormattingCustomizationValue Get() { } public aweXpect.Customization.CustomizationLifetime Update(System.Func update) { } @@ -410,6 +411,7 @@ namespace aweXpect.Customization { public FormattingCustomizationValue() { } public int MaximumNumberOfCollectionItems { get; init; } + public int MaximumStringLength { get; init; } public int MinimumNumberOfCharactersAfterStringDifference { get; init; } } public class ReflectionCustomization : aweXpect.Customization.ICustomizationValueUpdater diff --git a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt index e700b7506..6e6c85bc8 100644 --- a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt +++ b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt @@ -388,6 +388,7 @@ namespace aweXpect.Customization public class FormattingCustomization : aweXpect.Customization.ICustomizationValueUpdater { public aweXpect.Customization.ICustomizationValueSetter MaximumNumberOfCollectionItems { get; } + public aweXpect.Customization.ICustomizationValueSetter MaximumStringLength { get; } public aweXpect.Customization.ICustomizationValueSetter MinimumNumberOfCharactersAfterStringDifference { get; } public aweXpect.Customization.AwexpectCustomization.FormattingCustomizationValue Get() { } public aweXpect.Customization.CustomizationLifetime Update(System.Func update) { } @@ -396,6 +397,7 @@ namespace aweXpect.Customization { public FormattingCustomizationValue() { } public int MaximumNumberOfCollectionItems { get; init; } + public int MaximumStringLength { get; init; } public int MinimumNumberOfCharactersAfterStringDifference { get; init; } } public class ReflectionCustomization : aweXpect.Customization.ICustomizationValueUpdater diff --git a/Tests/aweXpect.Core.Tests/Customization/CustomizeFormattingTests.cs b/Tests/aweXpect.Core.Tests/Customization/CustomizeFormattingTests.cs index 05b0750b6..37c4ddb07 100644 --- a/Tests/aweXpect.Core.Tests/Customization/CustomizeFormattingTests.cs +++ b/Tests/aweXpect.Core.Tests/Customization/CustomizeFormattingTests.cs @@ -20,15 +20,34 @@ public async Task MaximumNumberOfCollectionItems_ShouldBeUsedInFormatter() int[] items = Enumerable.Range(1, 6).ToArray(); using (IDisposable _ = Customize.aweXpect.Formatting().MaximumNumberOfCollectionItems.Set(3)) { - await That(Formatter.Format(items)).IsEqualTo("[1, 2, 3, …]"); + await That(ValueFormatters.Format(Formatter, items)).IsEqualTo("[1, 2, 3, …]"); } using (IDisposable _ = Customize.aweXpect.Formatting().MaximumNumberOfCollectionItems.Set(5)) { - await That(Formatter.Format(items)).IsEqualTo("[1, 2, 3, 4, 5, …]"); + await That(ValueFormatters.Format(Formatter, items)).IsEqualTo("[1, 2, 3, 4, 5, …]"); } - await That(Formatter.Format(items)).IsEqualTo("[1, 2, 3, 4, 5, 6]"); + await That(ValueFormatters.Format(Formatter, items)).IsEqualTo("[1, 2, 3, 4, 5, 6]"); + } + + [Fact] + public async Task MaximumStringLength_ShouldBeUsedInFormatter() + { + string stringWith100Chars = + "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt util"; + using (IDisposable _ = Customize.aweXpect.Formatting().MaximumStringLength.Set(6)) + { + await That(Formatter.Format(stringWith100Chars)).IsEqualTo("\"Lorem …\""); + } + + using (IDisposable _ = Customize.aweXpect.Formatting().MaximumStringLength.Set(99)) + { + await That(Formatter.Format(stringWith100Chars)).IsEqualTo( + "\"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt uti…\""); + } + + await That(Formatter.Format(stringWith100Chars)).IsEqualTo($"\"{stringWith100Chars}\""); } [Fact]