combine-schedulers
                                
                                 combine-schedulers copied to clipboard
                                
                                    combine-schedulers copied to clipboard
                            
                            
                            
                        Simulate the inaccuracy of schedulers
This is a fantastic library and aids testing of time based asynchrony really well. But in a way, it only simulates the happiest path due to the precision of the scheduler. As we all know, when a timer is set it will complete at a point of timer after the scheduled time, if only a fraction of a second after. In your videos on Clocks, you demonstrate how this drift can add relatively quickly.
Would it be possible to add a feature where we can test against these small inaccuracies? So after advancing the scheduler, rather than the schedulers' .now property being set exactly to the next scheduled actions date, it could be set with a defined drift, maybe even the .minimumTolerance. This way, if we need to, we can test against these small inaccuracies of timing that can add up after many events.
This may be a naive approach, but it appears to work and all the tests still pass. It allows for the creation of a new test scheduler where the now date is always set to the next action date plus the minimum tolerance.
public final class TestScheduler<SchedulerTimeType, SchedulerOptions> ... {
  // ...
  public let minimumTolerance: SchedulerTimeType.Stride
  public init(now: SchedulerTimeType, minimumTolerance: SchedulerTimeType.Stride = .zero) {
    self.now = now
    self.minimumTolerance = minimumTolerance
  }
  // in both advance methods update now to next.date but include minimumTolerance.
  public func advance(to instant: SchedulerTimeType) {
    while self.lock.sync(operation: { self.now }) <= instant {
      self.lock.lock()
      self.scheduled.sort { ($0.date, $0.sequence) < ($1.date, $1.sequence) }
      
      guard
        let next = self.scheduled.first,
        instant >= next.date
      else {
        self.now = instant
        self.lock.unlock()
        return
      }
      
      self.now = next.date.advanced(by: minimumTolerance) // <-- include minimum tolerance to have predictable inaccuracy
      self.scheduled.removeFirst()
      self.lock.unlock()
      next.action()
    }
  }
// create a new test scheduler that includes defined inaccuracy.
extension RunLoop {
  /// ...
  public static func inaccurate(
    by minimumTolerance: SchedulerTimeType.Stride
  ) -> TestSchedulerOf<RunLoop> {
    .init(now: .init(.init(timeIntervalSince1970: 0)), minimumTolerance: minimumTolerance)
  }
}
Hey @runloop, this is a really great idea! Wanna PR it?
I gave it a shot.
https://github.com/pointfreeco/combine-schedulers/pull/72