Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GenericCollectionAssertions.SatisfyRespectively: message formatting fails when nested message contains braces #1092

Closed
kennep opened this issue Jul 3, 2019 · 1 comment · Fixed by #1097

Comments

@kennep
Copy link

kennep commented Jul 3, 2019

Description

When using GenericCollectionAssertions.SatisfyRespectively, and the nested assertion failure message contains braces, message formatting will fail with a System.FormatException.

This happens because FailWith is called with a formatting message containing braces, but with zero message arguments, in these places:

SatisyRespectively (fails when the reason variable is a string containing braces):

   414              if (failuresFromInspectors.Any())
   415              {
   416                  string failureMessage = "Expected {context:collection} to satisfy all inspectors{reason}, but some inspectors are not satisfied:"
   417                      + Environment.NewLine
   418                      + string.Join(Environment.NewLine, failuresFromInspectors.Select(x => x.IndentLines()));
   419                  Execute.Assertion
   420                      .BecauseOf(because, becauseArgs)
   421                      .FailWith(failureMessage);
   422              }

CollectFailuresFromInspectors (fails when failures variable is a string containing braces):

   442                      if (inspectorFailures.Length > 0)
   443                      {
   444                          // Adding one tab and removing trailing dot to allow nested SatisfyRespectively
   445                          string failures = string.Join(Environment.NewLine, inspectorFailures.Select(x => x.IndentLines().TrimEnd('.')));
   446                          // FailWith formatting is not used because of extra quotes being added.
   447                          Execute.Assertion
   448                              .FailWith($"At index {index}:{Environment.NewLine}{failures}");
   449                      }

Complete minimal example reproducing the issue

byte[][] aa = { new byte[]{1} };

aa.Should().SatisfyRespectively( e => {
	e.Should().BeEquivalentTo(new byte[]{2, 3, 4});
});

Expected behavior:

Assertion failure with a message indicating that not all inspectors were satisfied, and that the expected and actual arrays at element 0 had different lengths.

Actual behavior:

Stack trace:

   System.FormatException : Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
  Stack Trace:
     at System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.Format(String format, Object[] args)
   at FluentAssertions.Execution.MessageBuilder.FormatArgumentPlaceholders(String failureMessage, Object[] failureArgs) in /home/kenneth/Projects/3rdParty/fluentassertions/Src/FluentAssertions/Execution/MessageBuilder.cs:line 90
   at FluentAssertions.Execution.MessageBuilder.Build(String message, Object[] messageArgs, String reason, ContextDataItems contextData, String identifier, String fallbackIdentifier) in /home/kenneth/Projects/3rdParty/fluentassertions/Src/FluentAssertions/Execution/MessageBuilder.cs:line 40
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc) in /home/kenneth/Projects/3rdParty/fluentassertions/Src/FluentAssertions/Execution/AssertionScope.cs:line 178
   at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args) in /home/kenneth/Projects/3rdParty/fluentassertions/Src/FluentAssertions/Execution/AssertionScope.cs:line 200
   at FluentAssertions.Collections.GenericCollectionAssertions`1.SatisfyRespectively(IEnumerable`1 expected, String because, Object[] becauseArgs) in /home/kenneth/Projects/3rdParty/fluentassertions/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs:line 419
   at FluentAssertions.Collections.GenericCollectionAssertions`1.SatisfyRespectively(Action`1[] elementInspectors) in /home/kenneth/Projects/3rdParty/fluentassertions/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs:line 362

Versions

Tested with
FluentAssertions 5.7.0
FluentAssertions from master: fdc2c7d
.Net Core 2.2 (Linux)

@jnyrup
Copy link
Member

jnyrup commented Aug 10, 2019

Just a heads up: 5.8.0 has been released with the fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants