11using System ;
22using System . Linq ;
3+ using System . Reactive ;
34using System . Reactive . Linq ;
5+ using System . Reactive . Subjects ;
46using System . Threading . Tasks ;
57
68using Bogus ;
@@ -30,12 +32,14 @@ public class GroupOnObservableFixture : IDisposable
3032 private readonly SourceCache < Person , string > _cache = new ( p => p . UniqueKey ) ;
3133 private readonly ChangeSetAggregator < Person , string > _results ;
3234 private readonly GroupChangeSetAggregator < Person , string , Color > _groupResults ;
35+ private readonly Subject < Unit > _grouperShutdown ;
3336 private readonly Faker < Person > _faker ;
3437 private readonly Randomizer _randomizer = new ( 0x3141_5926 ) ;
3538
3639 public GroupOnObservableFixture ( )
3740 {
3841 _faker = Fakers . Person . Clone ( ) . WithSeed ( _randomizer ) ;
42+ _grouperShutdown = new ( ) ;
3943 _results = _cache . Connect ( ) . AsAggregator ( ) ;
4044 _groupResults = _cache . Connect ( ) . GroupOnObservable ( CreateFavoriteColorObservable ) . AsAggregator ( ) ;
4145 }
@@ -179,7 +183,7 @@ public void GroupingSequenceCompletesWhenEmpty()
179183 }
180184
181185 [ Fact ]
182- public void AllSequencesCompleteWhenSourceIsDisposed ( )
186+ public void AllSequencesShouldCompleteWhenSourceAndGroupingObservablesComplete ( )
183187 {
184188 // Arrange
185189 _cache . AddOrUpdate ( _faker . Generate ( InitialCount ) ) ;
@@ -190,6 +194,7 @@ public void AllSequencesCompleteWhenSourceIsDisposed()
190194
191195 // Act
192196 _cache . Dispose ( ) ;
197+ _grouperShutdown . OnNext ( Unit . Default ) ;
193198
194199 // Assert
195200 results . IsCompleted . Should ( ) . BeTrue ( ) ;
@@ -243,9 +248,11 @@ public async Task ResultsContainsCorrectRegroupedValuesAsync()
243248 }
244249
245250 [ Theory ]
246- [ InlineData ( false ) ]
247- [ InlineData ( true ) ]
248- public void ResultCompletesOnlyWhenSourceCompletes ( bool completeSource )
251+ [ InlineData ( false , false ) ]
252+ [ InlineData ( true , false ) ]
253+ [ InlineData ( false , true ) ]
254+ [ InlineData ( true , true ) ]
255+ public void ResultCompletesOnlyWhenSourceAndAllGroupingObservablesComplete ( bool completeSource , bool completeGroups )
249256 {
250257 // Arrange
251258 _cache . AddOrUpdate ( _faker . Generate ( InitialCount ) ) ;
@@ -255,10 +262,14 @@ public void ResultCompletesOnlyWhenSourceCompletes(bool completeSource)
255262 {
256263 _cache . Dispose ( ) ;
257264 }
265+ if ( completeGroups )
266+ {
267+ _grouperShutdown . OnNext ( Unit . Default ) ;
268+ }
258269
259270 // Assert
260271 _results . IsCompleted . Should ( ) . Be ( completeSource ) ;
261- _groupResults . IsCompleted . Should ( ) . Be ( completeSource ) ;
272+ _groupResults . IsCompleted . Should ( ) . Be ( completeGroups && completeSource ) ;
262273 }
263274
264275 [ Fact ]
@@ -311,6 +322,7 @@ public void Dispose()
311322 _groupResults . Dispose ( ) ;
312323 _results . Dispose ( ) ;
313324 _cache . Dispose ( ) ;
325+ _grouperShutdown . Dispose ( ) ;
314326 }
315327
316328 private void RandomFavoriteColorChange ( )
@@ -342,6 +354,6 @@ private static void VerifyGroupingResults(ISourceCache<Person, string> cache, Ch
342354 groupResults . Groups . Items . ForEach ( group => group . Data . Count . Should ( ) . BeGreaterThan ( 0 , "Empty groups should be removed" ) ) ;
343355 }
344356
345- private static IObservable < Color > CreateFavoriteColorObservable ( Person person , string key ) =>
346- person . WhenPropertyChanged ( p => p . FavoriteColor ) . Select ( change => change . Value ) ;
357+ private IObservable < Color > CreateFavoriteColorObservable ( Person person , string key ) =>
358+ person . WhenPropertyChanged ( p => p . FavoriteColor ) . Select ( change => change . Value ) . TakeUntil ( _grouperShutdown ) ;
347359}
0 commit comments