Skip to content

Implement CollectionExtensions.TakeWhileBefore extensions#796

Merged
axunonb merged 3 commits into
mainfrom
wip/axunonb/pr/take-before
May 16, 2025
Merged

Implement CollectionExtensions.TakeWhileBefore extensions#796
axunonb merged 3 commits into
mainfrom
wip/axunonb/pr/take-before

Conversation

@axunonb
Copy link
Copy Markdown
Collaborator

@axunonb axunonb commented May 15, 2025

These are convenience methods for Enumerable.TakeWhile{TSource}(IEnumerable{TSource}, Func{TSource, bool}).

Resolves #787

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

❌ Your project status has failed because the head coverage (67%) is below the target coverage (80%). You can increase the head coverage or adjust the target coverage.

Impacted file tree graph

@@         Coverage Diff         @@
##           main   #796   +/-   ##
===================================
  Coverage    67%    67%           
===================================
  Files       105    106    +1     
  Lines      4419   4421    +2     
  Branches   1060   1060           
===================================
+ Hits       2940   2942    +2     
  Misses     1045   1045           
  Partials    434    434           
Files with missing lines Coverage Δ
Ical.Net/CollectionExtensions.cs 100% <100%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@axunonb axunonb changed the title ImplementCollectionExtensions.TakeBefore extensions Implement CollectionExtensions.TakeBefore extensions May 15, 2025
@axunonb axunonb marked this pull request as ready for review May 15, 2025 11:24
@axunonb axunonb requested a review from minichma May 15, 2025 11:25
minichma
minichma previously approved these changes May 15, 2025
Comment thread Ical.Net/CollectionExtensions.cs Outdated
/// The elements of the sequence of occurrences to only include those that start before the specified period end.
/// </returns>
public static IEnumerable<Occurrence> TakeBefore(this IEnumerable<Occurrence> sequence, CalDateTime? periodEnd)
=> (periodEnd == null) ? sequence : sequence.TakeWhile(p => p.Period.StartTime < periodEnd);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think periodEnd shouldn't be nullable. In the test space I made it nullable to act as a c&p replacement for the previous periodEnd param and its used just internally (actually this was part of the reason not making it public). But in this case I feel its not quite natural allowing to pass a null value, making it a noop. I therefore suggest making it non-null. In the test projects we could keep an internal extension method that still allows passing null for simplicity.

Copy link
Copy Markdown
Collaborator Author

@axunonb axunonb May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this was my first thought as well.: null would be a noop. Just like "abc".ToString() returning this.
However, users could then use toDate e.g. in a loop, without caring for nullability. See our own tests below.

If toDate was not nullable, we could (would) write the unit test RecurrenceTests.EventOccurrenceTest(...) like

var occurrences = toDate != null
    ? evt.GetOccurrences(fromDate).TakeBefore(toDate).ToList()
    : evt.GetOccurrences(fromDate).ToList();

without the need for an extension method just for this test.
What's better?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer the not nullable, just like .TakeWhile or .Skip don't accept null. For our own use we can add the nullable version, like everyone can easily do. Outside of test cases I wouldn't expect it to be a common case that invocations need the nullable version. Either they want to limit or they don't I'd expect.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then so be it.

Comment thread Ical.Net/CollectionExtensions.cs Outdated
/// <returns>
/// The elements of the sequence of periods to only include those that start before the specified period end.
/// </returns>
public static IEnumerable<Period> TakeBefore(this IEnumerable<Period> sequence, CalDateTime? periodEnd)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the naming: TakeBefore could be interpreted as filter (aka 'take all items from the sequence where the value is before x). In this interpretation it wouldn't reflect the fact that 'Before' refers to the items in the sequence, which means _take those that are returned before hitting or exceeding the threshold). An alternative could be TakeWhileBefore, which more clearly suggests 'take all items from the sequence while the their date value is before x', but the name is a bit clumsy. Not sure.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, really makes sense to think about the best term. Coming back to one of the initial ideas using like .GetOccurrences(...).WhileBefore(...) sounded quite natural, and it was short... Better?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds better to me. It's not quite in line with linq naming though. Not sure it has to be in this case. On the other hand, if it is named like TakeWhileXxx it could be easier to find, because it pops up in auto completion when people are looking for linq operators. Anyone, any of the discussed names is good.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"easier to find" is convincing for .TakeWhileBefore(...), tnx

@sonarqubecloud
Copy link
Copy Markdown

@axunonb axunonb requested a review from minichma May 15, 2025 22:23
@axunonb axunonb changed the title Implement CollectionExtensions.TakeBefore extensions Implement CollectionExtensions.WhileTakeBefore extensions May 15, 2025
@axunonb axunonb changed the title Implement CollectionExtensions.WhileTakeBefore extensions Implement CollectionExtensions.TakeWhileBefore extensions May 15, 2025
@axunonb axunonb merged commit 31cb185 into main May 16, 2025
8 of 9 checks passed
@axunonb axunonb deleted the wip/axunonb/pr/take-before branch May 16, 2025 06:58
@axunonb
Copy link
Copy Markdown
Collaborator Author

axunonb commented May 16, 2025

@minichma BTW quite nice how code quality has improved since October 2024: From 274 issues to 105 now.
https://sonarcloud.io/project/overview?id=ical-org_ical.net
Once you login to Sonar using your GitHub account I should be able to give you permissions to more insights.

@minichma
Copy link
Copy Markdown
Collaborator

@minichma BTW quite nice how code quality has improved since October 2024: From 274 issues to 105 now. https://sonarcloud.io/project/overview?id=ical-org_ical.net Once you login to Sonar using your GitHub account I should be able to give you permissions to more insights.

Very nice to see. It seems lots of the improvements coming from NRT - great work!

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

Successfully merging this pull request may close these issues.

Add TakeBefore extension methods for IEnumerable<Period> and IEnumerable<Occurrence> to public API

2 participants