Skip to content

ArgumentOutOfRangeException when formatting objects using UseLineBreaks #2695

@jnyrup

Description

@jnyrup

Description

When using ReferenceTypeAssertions.BeSameAs and failing I got a ArgumentOutOfRangeException instead of an XunitException.

From the stack trace the problem lies somewhere in the formatting of the subject combined with using UseLineBreaks.

Only a few assertions specify UseLineBreaks per default, which is why we might not have seen this before.

Reproduction Steps

[Fact]
public void Array_of_arrays_of_toStringable_objects()
{
    var sigmets = new Point[][]
    {
        [new Point()],
        [new Point()],
    };

    Formatter.ToString(sigmets, new() { UseLineBreaks = true });
}

[Fact]
public void Array_of_objects_with_array_of_toStringable_objects()
{
    var sigmets = new[]
    {
        new
        {
            Points = new Point[] { new() }
        },
        new
        {
            Points = new Point[] { new() }
        }
    };

    Formatter.ToString(sigmets, new() { UseLineBreaks = true });
}

private class Point
{
    public override string ToString() => "P";
}

Expected behavior

Both tests should be able to complete without throwing an exception

Actual behavior

Array_of_arrays_of_toStringable_objects:

Message: 
Test method TestProject30.UnitTest1.Array_of_arrays_of_toStringable_objects threw exception: 
System.ArgumentOutOfRangeException: startIndex ('3') must be less than or equal to '0'. (Parameter 'startIndex')
Actual value was 3.

  Stack Trace: 
ArgumentOutOfRangeException.ThrowGreater[T](T value, T other, String paramName)
String.Insert(Int32 startIndex, String value)
PossibleMultilineFragment.InsertLineOrFragment(String fragment)
EnumerableValueFormatter.Format(Object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild)
Formatter.Format(Object value, FormattedObjectGraph output, FormattingContext context, FormatChild formatChild)
Formatter.ToString(Object value, FormattingOptions options)
UnitTest1.Array_of_arrays_of_toStringable_objects() line 17
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Array_of_objects_with_array_of_toStringable_objects:

Message: 
Test method TestProject30.UnitTest1.Array_of_objects_with_array_of_toStringable_objects threw exception: 
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

  Stack Trace: 
List`1.get_Item(Int32 index)
PossibleMultilineFragment.InsertAtStartOfLine(Int32 lineIndex, String insertion)
PossibleMultilineFragment.AddStartingLineOrFragment(String fragment)
EnumerableValueFormatter.Format(Object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild)
Formatter.Format(Object value, FormattedObjectGraph output, FormattingContext context, FormatChild formatChild)
Formatter.FormatChild(String path, Object value, FormattedObjectGraph output, FormattingContext context, FormattingOptions options, ObjectGraph graph)
<>c__DisplayClass6_0.<FormatChild>b__0(String childPath, Object childValue, FormattedObjectGraph nestedOutput)
DefaultValueFormatter.WriteMemberValueTextFor(Object value, MemberInfo member, FormattedObjectGraph formattedGraph, FormatChild formatChild)
DefaultValueFormatter.WriteMemberValues(Object obj, MemberInfo[] members, FormattedObjectGraph formattedGraph, FormatChild formatChild)
DefaultValueFormatter.WriteTypeValue(Object obj, FormattedObjectGraph formattedGraph, FormatChild formatChild, Type type)
DefaultValueFormatter.WriteTypeAndMemberValues(Object obj, FormattedObjectGraph formattedGraph, FormatChild formatChild)
DefaultValueFormatter.Format(Object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild)
Formatter.Format(Object value, FormattedObjectGraph output, FormattingContext context, FormatChild formatChild)
Formatter.FormatChild(String path, Object value, FormattedObjectGraph output, FormattingContext context, FormattingOptions options, ObjectGraph graph)
<>c__DisplayClass5_0.<ToString>b__0(String path, Object childValue, FormattedObjectGraph output)
EnumerableValueFormatter.Format(Object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild)
Formatter.Format(Object value, FormattedObjectGraph output, FormattingContext context, FormatChild formatChild)
Formatter.ToString(Object value, FormattingOptions options)
UnitTest1.Array_of_objects_with_array_of_toStringable_objects() line 35
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Regression?

Yes

In 6.11.0 Formatter.ToString doesn't throw.

Known Workarounds

No response

Configuration

Tried with both Version 6.12 and develop

Other information

By looking in the release notes for 6.12 I suspect #2144
CC: @benagain

Are you willing to help with a pull-request?

Yes, if anyone can figure out what the problem is

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions