8000 Implement is_sorted for collections by selakavon · Pull Request #99 · assertpy/assertpy · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@selakavon
Copy link

is_sorted functionality for collections. operator.ge as a default parameter, accepting a single comparing function or list of them.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.004%) to 99.822% when pulling 0977148 on selakavon:collection_is_sorted into c0989de on ActivisionGameScience:master.

@selakavon selakavon marked this pull request as ready for review November 9, 2019 12:19
@selakavon selakavon changed the title Added is_sorted for collections Implement is_sorted for collections Nov 9, 2019
@saturnboy saturnboy self-assigned this Nov 10, 2019
@saturnboy saturnboy added this to the v1.0 milestone Nov 10, 2019
@saturnboy
Copy link
Contributor
saturnboy commented Nov 11, 2019

@selakavon can you give me the argument for why

assert_that(foo).is_sorted()

is way better than:

assert_that(foo).is_equal_to(sorted(foo))

@selakavon
Copy link
Author

There are a few advantages from my point of view:

  1. is_sorted syntax is more easily readable
  2. performance - in the worst case not having to sort the array but just checking consequent elements is few times faster. Usually first not sorted elements are found sooner.
  3. multiple comparing operators can be used (combined by OR) - not sure it's a good idea though, this could an independent enhancement implemented in a general way, i.e.:
assert_that(foo).one_of(
                   is_equal_to(sorted(foo)), 
                   is_equal_to(sorted(foo, reverse=True))
)

I am looking forward to reading your opinions on those. Hopefully, I haven't missed anything too obvious :)

@saturnboy
Copy link
Contributor

@selakavon I don't love the ORing, as I feel like it allows an assertion author too much flexibility. A test is like a spec...it should say "I expect foo to be sorted" not "I guess foo is sorted ascending or descending, but I'm really not sure which". Similarly, I don't love a theoretical one_of() operator...tests are not guesses. I'd be happy to see a use case where I'm wrong.

For is_sorted(), what if the API was simply:

assert_that([1,2,5,6]).is_sorted()
assert_that([6,5,2,1]).is_sorted(reverse=True)

That feels like a good mirror of:

assert_that(sorted(foo)).is_sorted()
assert_that(sorted(foo, reverse=True)).is_sorted(reverse=True)

Would that fit your needs?

@selakavon
Copy link
Author

@saturnboy
Thank you for the explanation. What I wanted to achieve is to test if the list is monotonic. Now I have realized I was being lazy, I should know which way the list should be sorted.

I like is_sorted(reverse=True).
Would you like me to alter the implementation that way or do you prefer to keep only the is_equal_to(sorted(foo)) and close the PR?

@saturnboy
Copy link
Contributor
saturnboy commented Nov 14, 2019

Let's move forward with is_sorted():

assert_that([1,2,5,6]).is_sorted()
assert_that([6,5,2,1]).is_sorted(reverse=True)

@saturnboy saturnboy closed this in 0de9ebe Nov 17, 2019
@saturnboy
Copy link
Contributor

@selakavon i ended up rewriting this PR to make is_sorted() exactly mirror the API of python's sorted built-in.

You can now do all this:

assert_that([1,2,3]).is_sorted()
assert_that((3,2,1)).is_sorted(reverse=True)

assert_that(['a','b','c']).is_sorted()
assert_that([{'name':'bob', 'age':1}, {'name':'alice', 'age':2}]).is_sorted(key=lambda x: x['age'])

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

0