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

[Feature]: Multi dimension arrays assertions #2596

Open
Meir017 opened this issue Feb 29, 2024 · 10 comments
Open

[Feature]: Multi dimension arrays assertions #2596

Meir017 opened this issue Feb 29, 2024 · 10 comments
Labels
api-approved API was approved, it can be implemented feature

Comments

@Meir017
Copy link
Member

Meir017 commented Feb 29, 2024

Background and motivation

Allowing to fluently assert on multi-dimension arrays

background - fluentassertions/fluentassertions.analyzers#309

Are you willing help with a pull-request?

Yes

@dennisdoomen
Copy link
Member

You can already use BeEquivalenTo for that. It has support for multi-dimensional arrays.

@dennisdoomen
Copy link
Member

But what kind of assertion would you suggest?

@Meir017
Copy link
Member Author

Meir017 commented Mar 1, 2024

for asserting the Length and GetLength functionality

maybe something like this

var array = new string[2,3] { { "a", "b", "c" }, { "d", "e", "f" } };
array.Should().BeEmpty();
array.Should().NotBeEmpty();

array.Should().HaveElementAt(0, 0, "a");
array.Should().HaveElementAt(1, 2, "f");

array.Should().HaveTotalLength(6);
array.Should().HaveDimensionLength(0, 2);
array.Should().HaveDimensionLength(1, 3);

@dennisdoomen
Copy link
Member

I like that. What do you think @jnyrup ?

@dennisdoomen dennisdoomen added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Mar 2, 2024
@Meir017
Copy link
Member Author

Meir017 commented Mar 2, 2024

I'm wondering if for each different array dimension there should be a dedicated assertions class, this will allow to have strongly-typed assertions and not just use the System.Array type.

this would mean that instead of HaveDimensionLength there could be a dedicated method for each dimension length

something like this:

public static class Extensions
{
    public static TwoDimensionalArrayAssertions<T> Should<T>(this T[,] actual) => new(actual);
    public static ThreeDimensionalArrayAssertions<T> Should<T>(this T[,,] actual) => new(actual);
    public static FourDimensionalArrayAssertions<T> Should<T>(this T[,,,] actual) => new(actual);
}

public class TwoDimensionalArrayAssertions<T>
{
    public TwoDimensionalArrayAssertions(T[,] array) { }
}
public class ThreeDimensionalArrayAssertions<T>
{
    public ThreeDimensionalArrayAssertions(T[,,] array) { }
}
public class FourDimensionalArrayAssertions<T>
{
    public FourDimensionalArrayAssertions(T[,,,] array) { }
}

@dennisdoomen
Copy link
Member

That's possible, but this is the first time in 13 years that somebody suggests this feature, so your original proposal should be good enough.

@Meir017
Copy link
Member Author

Meir017 commented Mar 3, 2024

I think that a generic assertion extension will not work here

public static ArrayAssertions Should(this Array array) => new ArrayAssertions(array);

I think that the assertion extensions need to be for each dimension separately, otherwise when using a single-dimension array the extension method used will be the new one instead of the Collections.GenericCollectionAssertions<T>

so we would need something like this -

public static class Ex
{
    public static MultiDimensionArrayAssertions Should<T>(this T[,] array) => new MultiDimensionArrayAssertions(array);
    public static MultiDimensionArrayAssertions Should<T>(this T[,,] array) => new MultiDimensionArrayAssertions(array);
    public static MultiDimensionArrayAssertions Should<T>(this T[,,,] array) => new MultiDimensionArrayAssertions(array);
    // more dimensions ...
}

public class MultiDimensionArrayAssertions // what should this extend from?
{
    public MultiDimensionArrayAssertions(Array array) { }
}

@dennisdoomen
Copy link
Member

Yeah, you're right. You can define an extension method on Array, but for single-dimension arrays, it'll result in ambiguous calls.

@jnyrup
Copy link
Member

jnyrup commented Mar 24, 2024

I agree about not going down the TwoDimensionalArrayAssertions path.

Since Array.GetValue() has overloads for up to three indices before deferring to params int[] indices or params long[] indices, Let's as well go with three Shoulds for T[,], T[,,] and T[,,,].
If users needs more, they can always add those overloads themselves as they just resolve ambiguity and forward to MultiDimensionArrayAssertions.

Since we haven't had requests for multi-dimensional arrays, I don't think we should duplicate all functionality from GenericCollectionAssertions

I suggest starting out soft with these:

  • BeEmpty()
  • NotBeEmpty()
  • HaveCount(int expected)
  • NotHaveCount(int unexpected)

@dennisdoomen
Copy link
Member

Let's as well go with three Shoulds for T[,], T[,,] and T[,,,].

That settles it then

@dennisdoomen dennisdoomen added api-approved API was approved, it can be implemented and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Mar 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved API was approved, it can be implemented feature
Projects
None yet
Development

No branches or pull requests

3 participants