Repository: AwesomeAssertions/AwesomeAssertions
Pull request #100: Make displayed length in `StringEqualityStrategy` configurable
Author: login: vbreuss
Created: 2025-03-17T10:27:00Z | Merged: 2025-03-20T09:33:27Z

Follow-up to #94 (fixes #46):

Add a new configuration option `AssertionConfiguration.Current.Formatting.StringComparisonLength` which sets the default number of characters shown when highlighting the difference of two strings.


## IMPORTANT 

* [ ] If the PR touches the public API, the changes have been approved in a separate issue with the "api-approved" label.
* [x] The code complies with the [Coding Guidelines for C#](https://www.csharpcodingguidelines.com/).
* [x] The changes are covered by unit tests which follow the Arrange-Act-Assert syntax and the naming conventions such as is used [in these tests](../tree/main/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs#L51-L430).
* [x] If the PR adds a feature or fixes a bug, please update [the release notes](../tree/main/docs/_pages/releases.md) with a functional description that explains what the change means to consumers of this library, which are published on the [website](https://awesomeassertions.org/releases).
* [x] If the PR changes the public API the changes needs to be included by running [AcceptApiChanges.ps1](../tree/main/AcceptApiChanges.ps1) or [AcceptApiChanges.sh](../tree/main/AcceptApiChanges.sh).
* [ ] If the PR affects [the documentation](../tree/main/docs/_pages), please include your changes in this pull request so the documentation will appear on the [website](https://awesomeassertions.org/introduction).
    * [ ] Please also run `./build.sh --target spellcheck` or `.\build.ps1 --target spellcheck` before pushing and check the good outcome


Linked issue #46: Output of StringEqualityStrategy trims string after 5 to 15 chars
The behavior of the StringEqualityStrategy has changed. Now the strings are trimmed after 5 .. 15 chars. This make it harder to find the failure of the test. 
Only a part of the string (e.g. Error Message or Validation Message) is not visible in test output.

This behavior is even worse when you have messages that stars similar or you have added context to the message and the context is gone because you added it to the end.

It would be nice to have an option to disable the trimming of a string or the define the max length.

Linked issue comments: user: login: vbreuss
created_at: 2025-02-27T11:46:18Z
body: There was a lot of discussion on the pros and cons in https://github.com/fluentassertions/fluentassertions/issues/2050.
That said, I also increased the default number of displayed characters in [aweXpect](https://github.com/aweXpect/aweXpect/blob/main/Source/aweXpect.Core/Core/StringDifference.cs#L261), but it should be quite easy to adjust or configure the number of displayed characters in [`StringEqualityStrategy`](https://github.com/AwesomeAssertions/AwesomeAssertions/blob/main/Src/FluentAssertions/Primitives/StringEqualityStrategy.cs#L209).

Please keep in mind, that multi-line-strings are displayed in a single line, so for large strings to display everything might not be a good solution...
author_association: CONTRIBUTOR
user: login: cbersch
created_at: 2025-03-09T14:50:04Z
body: Basically I'm open to change this, but I don't know about the reason for choosing the current value. (@vbreuss do you remember?)

I read all comments and conversations of the linked PR, but found no discussions regarding those values (only about one-based indexing).

Regarding configurability: That are a lot of numbers to configure. They could be bundled in a respective object, which is attached to the `IEquivalencyOptions`?
author_association: MEMBER
user: login: vbreuss
created_at: 2025-03-09T16:22:36Z
body: @cbersch 
The values were completely arbitrary based on the minimal examples in the pull request. I think it would make sense to increase them to a more meaningful value per default and also make them configurable.
As far as I understand the use case, it would be probably sufficient to just increase the lengths in [`GetLengthOfPhraseToShowOrDefaultLength`](https://github.com/AwesomeAssertions/AwesomeAssertions/blob/main/Src/FluentAssertions/Primitives/StringEqualityStrategy.cs#L209) e.g. to
```csharp
        int minLength = 45;
        int defaultLength = minLength + 5;
        int maxLength = minLength + 15;

```
This would search for a word boundary between 45 and 60 characters after the first mismatch and if none is found defaults back to display 50 characters.

This way you could make the `minLength` configurable and allow an easy adjustment on the user needs...

author_association: CONTRIBUTOR
user: login: SchneiderMK
created_at: 2025-03-10T08:16:19Z
body: @cbersch Yes your recommendation would fix my problem. 
author_association: NONE
user: login: cbersch
created_at: 2025-03-13T10:36:05Z
body: Sounds reasonable, xUnit uses 50 characters: https://github.com/xunit/xunit/blob/4f4077c0918086a4dd223a4df4c6ca7175808c38/src/common/EnvironmentVariables.cs#L19

Considering, that options for the string comparison are currently part of the `IEquivalencyOptions`, a configurable value would also need to be defined there.

Possible API (Just to write it down, I'm not happy with the names, yet)

```C#
public interface IEquivalencyOptions
{
    ...
    int StringPrintLength { get; }
}

public abstract class SelfReferenceEquivalencyOptions<TSelf>
{
    ...
    public TSelf PrintingStringUpToLength(int stringPrintLength);
}
```

Configuration would then be done with 
```C#
AssertionEngine.Configuration.Equivalency.Modify(cfg => cfg.PrintingStringUpToLength(27));
```

author_association: MEMBER
user: login: vbreuss
created_at: 2025-03-13T11:36:47Z
body: @cbersch:

I created a PR with the change of the default behaviour (and adapted the tests). It should then simplify using a configuration value...
author_association: CONTRIBUTOR
user: login: vbreuss
created_at: 2025-03-16T07:21:09Z
body: @cbersch : I think we should re-open the issue, as the configuration option is not yet implemented.
author_association: CONTRIBUTOR

Diff:
diff --git a/Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs b/Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
index b01bfcd99..efe1ccf00 100644
--- a/Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
+++ b/Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
@@ -26,6 +26,7 @@ public string ValueFormatterAssembly
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringPrintLength = StringPrintLength,
             ScopedFormatters = [.. ScopedFormatters],
             ValueFormatterAssembly = ValueFormatterAssembly,
             ValueFormatterDetectionMode = ValueFormatterDetectionMode
diff --git a/Src/FluentAssertions/Formatting/FormattingOptions.cs b/Src/FluentAssertions/Formatting/FormattingOptions.cs
index 5c82dcbc0..a5873e180 100644
--- a/Src/FluentAssertions/Formatting/FormattingOptions.cs
+++ b/Src/FluentAssertions/Formatting/FormattingOptions.cs
@@ -42,6 +42,22 @@ public class FormattingOptions
     /// </remarks>
     public int MaxLines { get; set; } = 100;
 
+    /// <summary>
+    /// Sets the default number of characters shown when printing the difference of two strings.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The actual number of shown characters depends on the word-boundary-algorithm.<br />
+    /// This algorithm searches for a word boundary (a blank) in the range from 5 characters previous and 10 characters after the
+    /// <see cref="StringPrintLength"/>. If found it displays a full word, otherwise it falls back to the <see cref="StringPrintLength"/>.
+    /// </para>
+    /// <para>
+    /// This property is not thread-safe and should not be modified through <see cref="AssertionConfiguration"/> from within a unit test.
+    /// See the <see href="https://awesomeassertions.org/extensibility/#thread-safety">docs</see> on how to safely use it.
+    /// </para>
+    /// </remarks>
+    public int StringPrintLength { get; set; } = 50;
+
     /// <summary>
     /// Removes a scoped formatter that was previously added through <see cref="FormattingOptions.AddFormatter"/>.
     /// </summary>
@@ -71,6 +87,7 @@ internal FormattingOptions Clone()
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringPrintLength = StringPrintLength,
             ScopedFormatters = [.. ScopedFormatters],
         };
     }
diff --git a/Src/FluentAssertions/Primitives/StringEqualityStrategy.cs b/Src/FluentAssertions/Primitives/StringEqualityStrategy.cs
index e741f9162..9431c69df 100644
--- a/Src/FluentAssertions/Primitives/StringEqualityStrategy.cs
+++ b/Src/FluentAssertions/Primitives/StringEqualityStrategy.cs
@@ -212,9 +212,9 @@ private static int GetStartIndexOfPhraseToShowBeforeTheMismatchingIndex(string v
     /// </remarks>
     private static int GetLengthOfPhraseToShowOrDefaultLength(string value)
     {
-        const int minLength = 45;
-        const int defaultLength = minLength + 5;
-        const int maxLength = minLength + 15;
+        var defaultLength = AssertionConfiguration.Current.Formatting.StringPrintLength;
+        int minLength = defaultLength - 5;
+        int maxLength = defaultLength + 10;
         const int lengthOfWhitespace = 1;
 
         var indexOfWordBoundary = value
diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt
index 922035000..40ff5e70d 100644
--- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt
+++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt
@@ -1407,6 +1407,7 @@ namespace FluentAssertions.Formatting
         public FormattingOptions() { }
         public int MaxDepth { get; set; }
         public int MaxLines { get; set; }
+        public int StringPrintLength { get; set; }
         public bool UseLineBreaks { get; set; }
         public void AddFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
         public void RemoveFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt
index e60680035..a760cc533 100644
--- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt
+++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt
@@ -1426,6 +1426,7 @@ namespace FluentAssertions.Formatting
         public FormattingOptions() { }
         public int MaxDepth { get; set; }
         public int MaxLines { get; set; }
+        public int StringPrintLength { get; set; }
         public bool UseLineBreaks { get; set; }
         public void AddFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
         public void RemoveFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt
index 65dfdeec4..faae02317 100644
--- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt
+++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt
@@ -1351,6 +1351,7 @@ namespace FluentAssertions.Formatting
         public FormattingOptions() { }
         public int MaxDepth { get; set; }
         public int MaxLines { get; set; }
+        public int StringPrintLength { get; set; }
         public bool UseLineBreaks { get; set; }
         public void AddFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
         public void RemoveFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt
index 0b334b52d..7594a2d19 100644
--- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt
+++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt
@@ -1407,6 +1407,7 @@ namespace FluentAssertions.Formatting
         public FormattingOptions() { }
         public int MaxDepth { get; set; }
         public int MaxLines { get; set; }
+        public int StringPrintLength { get; set; }
         public bool UseLineBreaks { get; set; }
         public void AddFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
         public void RemoveFormatter(FluentAssertions.Formatting.IValueFormatter formatter) { }
diff --git a/Tests/FluentAssertions.Specs/Configuration/FormattingOptionsSpecs.cs b/Tests/FluentAssertions.Specs/Configuration/FormattingOptionsSpecs.cs
index f4d3d11e6..da46653ce 100644
--- a/Tests/FluentAssertions.Specs/Configuration/FormattingOptionsSpecs.cs
+++ b/Tests/FluentAssertions.Specs/Configuration/FormattingOptionsSpecs.cs
@@ -18,10 +18,12 @@ public void When_global_formatting_settings_are_modified()
         AssertionConfiguration.Current.Formatting.UseLineBreaks = true;
         AssertionConfiguration.Current.Formatting.MaxDepth = 123;
         AssertionConfiguration.Current.Formatting.MaxLines = 33;
+        AssertionConfiguration.Current.Formatting.StringPrintLength = 321;
 
         AssertionScope.Current.FormattingOptions.UseLineBreaks.Should().BeTrue();
         AssertionScope.Current.FormattingOptions.MaxDepth.Should().Be(123);
         AssertionScope.Current.FormattingOptions.MaxLines.Should().Be(33);
+        AssertionScope.Current.FormattingOptions.StringPrintLength.Should().Be(321);
     }
 
     [Fact]
diff --git a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs
index 788fd49e7..cf430112c 100644
--- a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs
+++ b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs
@@ -14,6 +14,35 @@ namespace FluentAssertions.Specs.Formatting;
 [Collection("FormatterSpecs")]
 public sealed class FormatterSpecs : IDisposable
 {
+    [Fact]
+    public void Use_configuration_when_highlighting_string_difference()
+    {
+        // Arrange
+        string subject = "this is a very long string with lots of words that most won't be displayed in the error message!";
+        string expected = "this is another string that differs after a couple of words.";
+        Action action = () => subject.Should().Be(expected);
+
+        int previousStringPrintLength = AssertionConfiguration.Current.Formatting.StringPrintLength;
+        try
+        {
+            // Act
+            AssertionConfiguration.Current.Formatting.StringPrintLength = 10;
+
+            // Assert
+            action.Should().Throw<Exception>().WithMessage("""
+                                                           *
+                                                                       ↓ (actual)
+                                                             "this is a very long…"
+                                                             "this is another…"
+                                                                       ↑ (expected).
+                                                           """);
+        }
+        finally
+        {
+            AssertionConfiguration.Current.Formatting.StringPrintLength = previousStringPrintLength;
+        }
+    }
+
     [Fact]
     public void When_value_contains_cyclic_reference_it_should_create_descriptive_error_message()
     {
diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md
index 5ffcc8f42..6db403e00 100644
--- a/docs/_pages/releases.md
+++ b/docs/_pages/releases.md
@@ -11,6 +11,8 @@ sidebar:
 
 ### What's new
 * Add `ForConstraint` to `GivenSelector<T>` allowing further chaining after `.Then` - [#44](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/44)
+* Increase default displayed length in `StringEqualityStrategy` - [#94](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/94)
+* Make displayed length in `StringEqualityStrategy` configurable - [#100](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100)
 
 ### Fixes
 * Fixed formatting of failure messages when comparing strings with braces - [#96](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/96)


Reviews:
user: login: ITaluone
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T13:11:19Z
user: login: cbersch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T17:49:57Z
user: login: vbreuss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T19:37:53Z
user: login: cbersch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T08:16:05Z
user: login: vbreuss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T08:28:48Z
user: login: cbersch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T08:50:05Z
user: login: ITaluone
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T08:58:20Z
user: login: cbersch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T10:11:50Z
user: login: ITaluone
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T14:59:16Z
user: login: vbreuss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T06:12:16Z
user: login: vbreuss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T06:13:19Z
user: login: vbreuss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T06:18:15Z
user: login: cbersch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T06:54:59Z
user: login: cbersch
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-19T06:56:02Z
user: login: ITaluone
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T07:20:19Z
user: login: ITaluone
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T07:20:40Z
user: login: IT-VBFK
body: LGTM!

Thanks!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-20T07:21:41Z

Review comments:
diff_hunk: @@ -42,6 +42,20 @@ public class FormattingOptions
     /// </remarks>
     public int MaxLines { get; set; } = 100;
 
+    /// <summary>
+    /// Sets the default number of characters shown when highlighting the difference of two strings.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The actual number of shown characters depends on the word-boundary-algorithm.
+    /// </para>
+    /// <para>
+    /// This property is not thread-safe and should not be modified through <see cref="AssertionConfiguration"/> from within a unit test.
+    /// See the <see href="https://awesomeassertions.org/extensibility/#thread-safety">docs</see> on how to safely use it.
+    /// </para>
+    /// </remarks>
path: Src/FluentAssertions/Formatting/FormattingOptions.cs
user: login: ITaluone
body: Should we add a remark and one or two examples how the actual boundaries are calculated, so that one knows about what consequence this has?


created_at: 2025-03-17T13:08:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -26,6 +26,7 @@ public string ValueFormatterAssembly
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringComparisonLength = StringComparisonLength,
path: Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
user: login: cbersch
body: I'm not happy with that name, because it suggests, that it might alter the actual comparison, but not the actual printing/output.
My proposal was `StringPrintLength`, inspired by the xUnit naming of that property [PrintMaxStringLength](https://github.com/xunit/xunit/blob/4f4077c0918086a4dd223a4df4c6ca7175808c38/src%2Fcommon%2FEnvironmentVariables.cs#L10)
created_at: 2025-03-17T17:49:57Z
author_association: MEMBER
diff_hunk: @@ -26,6 +26,7 @@ public string ValueFormatterAssembly
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringComparisonLength = StringComparisonLength,
path: Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
user: login: vbreuss
body: I'm open for suggestions, but please keep in mind that it is not the maximum length but the fallback length of the word boundary algorithm. The actual length can be 5 characters less or 10 characters more...
created_at: 2025-03-17T19:37:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -26,6 +26,7 @@ public string ValueFormatterAssembly
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringComparisonLength = StringComparisonLength,
path: Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
user: login: cbersch
body: Ok, so my propsals are
* StringPrintLength
* StringComparisonPrintLength
created_at: 2025-03-18T08:16:04Z
author_association: MEMBER
diff_hunk: @@ -26,6 +26,7 @@ public string ValueFormatterAssembly
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringComparisonLength = StringComparisonLength,
path: Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
user: login: vbreuss
body: I would prefer `StringPrintLength`. Any objections form anybody?
created_at: 2025-03-18T08:28:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,6 +11,7 @@ sidebar:
 
 ### What's new
 * Add `ForConstraint` to `GivenSelector<T>` allowing further chaining after `.Then` - [#44](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/44)
+* Make displayed length in `StringEqualityStrategy` configurable - [#100](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100)
path: docs/_pages/releases.md
user: login: cbersch
body: I would also add the change of the default length:

```
* Increase default displayed length in `StringEqualityStrategy` - [#94](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/94)
```

created_at: 2025-03-18T08:50:05Z
author_association: MEMBER
diff_hunk: @@ -11,6 +11,7 @@ sidebar:
 
 ### What's new
 * Add `ForConstraint` to `GivenSelector<T>` allowing further chaining after `.Then` - [#44](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/44)
+* Make displayed length in `StringEqualityStrategy` configurable - [#100](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100)
path: docs/_pages/releases.md
user: login: ITaluone
body: Why do we want to link an issue here? The link to the PR has the link to the issue in the description 🤔
created_at: 2025-03-18T08:58:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,6 +11,7 @@ sidebar:
 
 ### What's new
 * Add `ForConstraint` to `GivenSelector<T>` allowing further chaining after `.Then` - [#44](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/44)
+* Make displayed length in `StringEqualityStrategy` configurable - [#100](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100)
path: docs/_pages/releases.md
user: login: cbersch
body: Both links are to PRs
created_at: 2025-03-18T10:11:50Z
author_association: MEMBER
diff_hunk: @@ -11,6 +11,7 @@ sidebar:
 
 ### What's new
 * Add `ForConstraint` to `GivenSelector<T>` allowing further chaining after `.Then` - [#44](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/44)
+* Make displayed length in `StringEqualityStrategy` configurable - [#100](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100)
path: docs/_pages/releases.md
user: login: ITaluone
body: Ou.. sorry I see :D
created_at: 2025-03-18T14:59:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -26,6 +26,7 @@ public string ValueFormatterAssembly
             UseLineBreaks = UseLineBreaks,
             MaxDepth = MaxDepth,
             MaxLines = MaxLines,
+            StringComparisonLength = StringComparisonLength,
path: Src/FluentAssertions/Configuration/GlobalFormattingOptions.cs
user: login: vbreuss
body: I renamed `StringComparisonLength` to `StringPrintLength`.
created_at: 2025-03-19T06:12:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,6 +11,7 @@ sidebar:
 
 ### What's new
 * Add `ForConstraint` to `GivenSelector<T>` allowing further chaining after `.Then` - [#44](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/44)
+* Make displayed length in `StringEqualityStrategy` configurable - [#100](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100)
path: docs/_pages/releases.md
user: login: vbreuss
body: I included the information for #94 in the release notes in [3ca1c03](https://github.com/AwesomeAssertions/AwesomeAssertions/pull/100/commits/3ca1c032e4004ecdb9befac41897b5710d33df39).
created_at: 2025-03-19T06:13:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -42,6 +42,20 @@ public class FormattingOptions
     /// </remarks>
     public int MaxLines { get; set; } = 100;
 
+    /// <summary>
+    /// Sets the default number of characters shown when highlighting the difference of two strings.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The actual number of shown characters depends on the word-boundary-algorithm.
+    /// </para>
+    /// <para>
+    /// This property is not thread-safe and should not be modified through <see cref="AssertionConfiguration"/> from within a unit test.
+    /// See the <see href="https://awesomeassertions.org/extensibility/#thread-safety">docs</see> on how to safely use it.
+    /// </para>
+    /// </remarks>
path: Src/FluentAssertions/Formatting/FormattingOptions.cs
user: login: vbreuss
body: I tried to roughly explain the word-boundary-algorithm, but I am unsure about adding examples. It's a lot of calculating characters and I fear it does not help making it clearer...
created_at: 2025-03-19T06:18:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -42,6 +42,20 @@ public class FormattingOptions
     /// </remarks>
     public int MaxLines { get; set; } = 100;
 
+    /// <summary>
+    /// Sets the default number of characters shown when highlighting the difference of two strings.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The actual number of shown characters depends on the word-boundary-algorithm.
+    /// </para>
+    /// <para>
+    /// This property is not thread-safe and should not be modified through <see cref="AssertionConfiguration"/> from within a unit test.
+    /// See the <see href="https://awesomeassertions.org/extensibility/#thread-safety">docs</see> on how to safely use it.
+    /// </para>
+    /// </remarks>
path: Src/FluentAssertions/Formatting/FormattingOptions.cs
user: login: cbersch
body: I think the description is clear enough. An example would become quite lengthy. The available tests are probably a better reference for examples.
created_at: 2025-03-19T06:54:59Z
author_association: MEMBER
diff_hunk: @@ -42,6 +42,20 @@ public class FormattingOptions
     /// </remarks>
     public int MaxLines { get; set; } = 100;
 
+    /// <summary>
+    /// Sets the default number of characters shown when highlighting the difference of two strings.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The actual number of shown characters depends on the word-boundary-algorithm.
+    /// </para>
+    /// <para>
+    /// This property is not thread-safe and should not be modified through <see cref="AssertionConfiguration"/> from within a unit test.
+    /// See the <see href="https://awesomeassertions.org/extensibility/#thread-safety">docs</see> on how to safely use it.
+    /// </para>
+    /// </remarks>
path: Src/FluentAssertions/Formatting/FormattingOptions.cs
user: login: ITaluone
body: Then I'm fine with this :)
created_at: 2025-03-20T07:20:19Z
author_association: CONTRIBUTOR

PR comments:
user: login: coveralls
created_at: 2025-03-17T11:48:26Z
body: ## Pull Request Test Coverage Report for [Build 13940120356](https://coveralls.io/builds/72803918)

### Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

- For more information on this, see <a target="_blank" href="https://docs.coveralls.io/build-types#tracking-coverage-changes-with-pull_request-builds">Tracking coverage changes with pull request builds</a>.
- To avoid this issue with future PRs, see these <a target="_blank" href="https://docs.coveralls.io/build-types#recommended-ci-configurations">Recommended CI Configurations</a>.
- For a quick fix, <a target="_blank" href="https://github.blog/changelog/2022-02-03-more-ways-to-keep-your-pull-request-branch-up-to-date/#update-your-pull-request-branch-by-rebasing">rebase this PR at GitHub</a>. Your next report should be accurate.

### Details

* **6** of **6**   **(100.0%)**  changed or added relevant lines in **3** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.001%**) to **97.424%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/72803918/badge)](https://coveralls.io/builds/72803918) |
| :-- | --: |
| Change from base [Build 13884418698](https://coveralls.io/builds/72747375): |  0.001% |
| Covered Lines: | 12304 |
| Relevant Lines: | 12487 |

---
##### 💛  - [Coveralls](https://coveralls.io)

author_association: NONE
user: login: coveralls
created_at: 2025-03-17T11:48:26Z
body: ## Pull Request Test Coverage Report for [Build 13897135183](https://coveralls.io/builds/72758899)


### Details

* **6** of **6**   **(100.0%)**  changed or added relevant lines in **3** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.001%**) to **97.424%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/72758899/badge)](https://coveralls.io/builds/72758899) |
| :-- | --: |
| Change from base [Build 13884418698](https://coveralls.io/builds/72747375): |  0.001% |
| Covered Lines: | 12304 |
| Relevant Lines: | 12487 |

---
##### 💛  - [Coveralls](https://coveralls.io)

author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-03-19T06:17:34Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=AwesomeAssertions_AwesomeAssertions&pullRequest=100)


author_association: NONE
user: login: cbersch
created_at: 2025-03-20T09:33:44Z
body: @vbreuss Thanks for the nice improvement.
author_association: MEMBER