1+ using System . Reactive . Concurrency ;
12using ByteSync . Business . Synchronizations ;
23using ByteSync . Interfaces . Controls . Synchronizations ;
34using ByteSync . Services . TimeTracking ;
45using FluentAssertions ;
6+ using Microsoft . Reactive . Testing ;
57using Moq ;
68using NUnit . Framework ;
79
@@ -10,23 +12,25 @@ namespace ByteSync.Tests.Services.TimeTracking;
1012[ TestFixture ]
1113public class SynchronizationDataTrackingStrategyTests
1214{
13- private static ( SynchronizationDataTrackingStrategy Sut , SynchronizationProcessData Data ) CreateSut ( )
15+ private static ( SynchronizationDataTrackingStrategy Sut , SynchronizationProcessData Data , IScheduler Scheduler ) CreateSut (
16+ IScheduler ? scheduler = null )
1417 {
1518 var data = new SynchronizationProcessData ( ) ;
1619
1720 var syncServiceMock = new Mock < ISynchronizationService > ( ) ;
1821 syncServiceMock . SetupGet ( x => x . SynchronizationProcessData ) . Returns ( data ) ;
1922
20- var sut = new SynchronizationDataTrackingStrategy ( syncServiceMock . Object ) ;
23+ var usedScheduler = scheduler ?? new TestScheduler ( ) ;
24+ var sut = new SynchronizationDataTrackingStrategy ( syncServiceMock . Object , usedScheduler ) ;
2125
22- return ( sut , data ) ;
26+ return ( sut , data , usedScheduler ) ;
2327 }
2428
2529 [ Test ]
2630 public void GetDataObservable_InitialEmission_IsZeroTuple ( )
2731 {
2832 // Arrange
29- var ( sut , data ) = CreateSut ( ) ;
33+ var ( sut , data , _ ) = CreateSut ( ) ;
3034 var evt = new AutoResetEvent ( false ) ;
3135 ( long Identified , long Processed ) ? captured = null ;
3236 Exception ? error = null ;
@@ -57,7 +61,7 @@ public void GetDataObservable_InitialEmission_IsZeroTuple()
5761 public void GetDataObservable_RunningWithZeroProgress_EmitsImmediately ( )
5862 {
5963 // Arrange
60- var ( sut , data ) = CreateSut ( ) ;
64+ var ( sut , data , _ ) = CreateSut ( ) ;
6165 var results = new List < ( long Identified , long Processed ) > ( ) ;
6266 using var sub = sut . GetDataObservable ( ) . Subscribe ( results . Add ) ;
6367
@@ -69,8 +73,6 @@ public void GetDataObservable_RunningWithZeroProgress_EmitsImmediately()
6973 } ) ;
7074 data . SynchronizationMainStatus . OnNext ( SynchronizationProcessStatuses . Running ) ;
7175
72- Thread . Sleep ( 200 ) ;
73-
7476 // Assert: should include the emitted data (non-skippable path)
7577 results . Should ( ) . Contain ( ( 1234L , 0L ) ) ;
7678 }
@@ -79,21 +81,21 @@ public void GetDataObservable_RunningWithZeroProgress_EmitsImmediately()
7981 public void GetDataObservable_RunningWithNonZeroProgress_IsSampled ( )
8082 {
8183 // Arrange
82- var ( sut , data ) = CreateSut ( ) ;
84+ var ( sut , data , scheduler ) = CreateSut ( ) ;
8385
8486 var results = new List < ( long Identified , long Processed ) > ( ) ;
8587 using var subscription = sut . GetDataObservable ( ) . Subscribe ( x => results . Add ( x ) ) ;
8688
8789 // Act: Push a few non-zero updates in quick succession (< 0.5s)
8890 data . SynchronizationMainStatus . OnNext ( SynchronizationProcessStatuses . Running ) ;
8991 data . SynchronizationProgress . OnNext ( new SynchronizationProgress { TotalVolumeToProcess = 1000 , SynchronizedVolume = 10 } ) ;
90- Thread . Sleep ( 100 ) ;
92+ ( scheduler as TestScheduler ) ! . AdvanceBy ( TimeSpan . FromMilliseconds ( 100 ) . Ticks ) ;
9193 data . SynchronizationProgress . OnNext ( new SynchronizationProgress { TotalVolumeToProcess = 1000 , SynchronizedVolume = 20 } ) ;
92- Thread . Sleep ( 100 ) ;
94+ ( scheduler as TestScheduler ) ! . AdvanceBy ( TimeSpan . FromMilliseconds ( 100 ) . Ticks ) ;
9395 data . SynchronizationProgress . OnNext ( new SynchronizationProgress { TotalVolumeToProcess = 1000 , SynchronizedVolume = 30 } ) ;
9496
95- // Wait sufficiently long for Sample( 0.5s) to produce an emission
96- Thread . Sleep ( 1500 ) ;
97+ // Advance virtual time beyond 0.5s to trigger Sample(0.5s)
98+ ( scheduler as TestScheduler ) ! . AdvanceBy ( TimeSpan . FromSeconds ( 1 ) . Ticks ) ;
9799
98100 // Assert: we should have at least one sampled emission with the latest values
99101 results . Should ( ) . Contain ( ( 1000L , 30L ) ) ;
0 commit comments