Skip to content

NUnit 2045: Assert.Multiple fixer might be slightly too greedy due to the lack of lookahead #777

@danielmarbach

Description

@danielmarbach

For example

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.That(configuration.Value1, Is.EqualTo(0));
            Assert.That(configuration.Value2, Is.EqualTo(0.0));
            Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
            Assert.That(configuration.Values, Is.Not.Empty);
            Assert.That(configuration.Values.ElementAt(1), Is.EqualTo(string.Empty));

will be rewritten to

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.Multiple(() =>
            {
                Assert.That(configuration.Value1, Is.EqualTo(0));
                Assert.That(configuration.Value2, Is.EqualTo(0.0));
                Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
                Assert.That(configuration.Values, Is.Not.Empty);
            });
            Assert.That(configuration.Values.ElementAt(1), Is.EqualTo(string.Empty));

while my intuition tells me it should do

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.Multiple(() =>
            {
                Assert.That(configuration.Value1, Is.EqualTo(0));
                Assert.That(configuration.Value2, Is.EqualTo(0.0));
                Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
            });
            Assert.That(configuration.Values, Is.Not.Empty);
            Assert.That(configuration.Values.ElementAt(1), Is.EqualTo(string.Empty));

or if Values would contain more complex objects

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.That(configuration.Value1, Is.EqualTo(0));
            Assert.That(configuration.Value2, Is.EqualTo(0.0));
            Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
            Assert.That(configuration.Values, Is.Not.Empty);
            Assert.That(configuration.Values[0].Value1, Is.EqualTo(string.Empty));
            Assert.That(configuration.Values[0].Value2, Is.EqualTo(string.Empty));
            Assert.That(configuration.Values[0].Value11, Is.EqualTo(string.Empty));

will be rewritten to

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.Multiple(() =>
            {
                Assert.That(configuration.Value1, Is.EqualTo(0));
                Assert.That(configuration.Value2, Is.EqualTo(0.0));
                Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
                Assert.That(configuration.Values, Is.Not.Empty);
            });
            Assert.Multiple(() =>
            {
                Assert.That(configuration.Values[0].Value1, Is.EqualTo(string.Empty));
                Assert.That(configuration.Values[0].Value2, Is.EqualTo(string.Empty));
                Assert.That(configuration.Values[0].Value11, Is.EqualTo(string.Empty));
            });

while my intuition would tell me it should do

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.Multiple(() =>
            {
                Assert.That(configuration.Value1, Is.EqualTo(0));
                Assert.That(configuration.Value2, Is.EqualTo(0.0));
                Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
            });
             Assert.That(configuration.Values, Is.Not.Empty);
            Assert.Multiple(() =>
            {
                Assert.That(configuration.Values[0].Value1, Is.EqualTo(string.Empty));
                Assert.That(configuration.Values[0].Value2, Is.EqualTo(string.Empty));
                Assert.That(configuration.Values[0].Value11, Is.EqualTo(string.Empty));
            });

Or with nested objects

            var configuration = new Configuration();
            Assert.That(configuration, Is.Not.Null);
            Assert.That(configuration.Value1, Is.EqualTo(0));
            Assert.That(configuration.Value2, Is.EqualTo(0.0));
            Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
            Assert.That(configuration.Inner, Is.Not.Null);
            Assert.That(configuration.Inner.Value1, Is.EqualTo(0));
            Assert.That(configuration.Inner.Value2, Is.EqualTo(0.0));
            Assert.That(configuration.Inner.Value11, Is.EqualTo(string.Empty));

it currently does

var configuration = new Configuration();
Assert.That(configuration, Is.Not.Null);
Assert.Multiple(() =>
{
    Assert.That(configuration.Value1, Is.EqualTo(0));
    Assert.That(configuration.Value2, Is.EqualTo(0.0));
    Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
    Assert.That(configuration.Inner, Is.Not.Null);
});
Assert.Multiple(() =>
{
    Assert.That(configuration.Inner.Value1, Is.EqualTo(0));
    Assert.That(configuration.Inner.Value2, Is.EqualTo(0.0));
    Assert.That(configuration.Inner.Value11, Is.EqualTo(string.Empty));
});

while my intuition tells me to

var configuration = new Configuration();
Assert.That(configuration, Is.Not.Null);
Assert.Multiple(() =>
{
    Assert.That(configuration.Value1, Is.EqualTo(0));
    Assert.That(configuration.Value2, Is.EqualTo(0.0));
    Assert.That(configuration.Value11, Is.EqualTo(string.Empty));
});
Assert.That(configuration.Inner, Is.Not.Null);
Assert.Multiple(() =>
{
    Assert.That(configuration.Inner.Value1, Is.EqualTo(0));
    Assert.That(configuration.Inner.Value2, Is.EqualTo(0.0));
    Assert.That(configuration.Inner.Value11, Is.EqualTo(string.Empty));
});

I do realize this can be highly depending on "taste". I think my intuition comes from the explanation of Assert.Multiple that an argument is not suffixed later and that is an indication that individual subtrees should be groupe together

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions