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

Adapt assertion extensions for Collections and Iterables to use bounded types #3960

Open
hanszt opened this issue Apr 2, 2024 · 3 comments

Comments

@hanszt
Copy link

hanszt commented Apr 2, 2024

Some of the assertions on collections now look like the following:

infix fun <T> Collection<T>.shouldHaveSize(size: Int): Collection<T> {
...
return this
}

I suggest to change this to

infix fun <T, C : Collection<T>> C.shouldHaveSize(size: Int): C {
   ...
   return this
}

The benefit of this is that you then can do the following:

val (_, _, third) = listOf(1, 2, 3) shouldHaveSize 3
third.shouldBe(3)

A second example:

When

fun <T> Iterable<T>.shouldNotContainDuplicates(): Iterable<T> {
   ...
   return this
}

is changed to

fun <T, I : Iterable<T>> I.shouldNotContainDuplicates(): I {
   ...
   return this
}

This will then allow you to write something like the following in your tests.

class Game(val name: String, players: Iterable<String>) : Iterable<String> by players

val game = Game("Risk", listOf("p1", "p2", "p3", "p4")).shouldNotContainDuplicates()
game.name shouldBe "Risk"

These are only a few examples of functions that could be improved in this way


@hanszt hanszt changed the title Addapt assertion extensions for Collections and Iterables to use bounded types Adapt assertion extensions for Collections and Iterables to use bounded types Apr 2, 2024
@hanszt
Copy link
Author

hanszt commented Apr 2, 2024

See also Pull request 3961

@AlexCue987
Copy link
Contributor

Personally I feel the following code would be confusing to me, as well as to most developers:
val game = Game("Risk", listOf("p1", "p2", "p3", "p4")).shouldNotContainDuplicates()
should I ever encounter that, I'd rather refactor it like this:

val game = Game("Risk", listOf("p1", "p2", "p3", "p4"))
game. players.shouldNotContainDuplicates()

So I don't perceive this change as a big improvement.

@hanszt
Copy link
Author

hanszt commented Apr 3, 2024

I see what you mean.

But as a more general guidline: Isn't it more desirable to have a return type that is more specific?

Something on the line of this post: https://stackoverflow.com/questions/3434367/is-it-better-to-return-the-most-specific-or-most-general-type-from-an-action-met

This makes the use of these functions more flexible don't you think? Especially in light of the first example above?
I'm curious what you think

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

No branches or pull requests

2 participants