sleep method Null safety

  1. @protected
Future<void> sleep(
  1. Duration duration,
  2. {required Stream<void>? cancelStream,
  3. bool error = false,
  4. String? message,
  5. required TestController tester}
)

Sleeps for the defined Duration. This accept an optional cancelStream which can be used to cancel the sleep. The error flag informs the sleeper about whether the duration is a standard duration or an error based timeout.

The optional message can be used to provide more details to the sleep step.

Implementation

@protected
Future<void> sleep(
  Duration duration, {
  required Stream<void>? cancelStream,
  bool error = false,
  String? message,
  required TestController tester,
}) async {
  if (duration.inMilliseconds > 0) {
    // Let's reduce the number of log entries to 1 per 100ms or 10 per second.
    var calcSteps = duration.inMilliseconds / 100;

    // However, let's put sanity limits.  At lest 10 events and no more than
    // 50.
    var steps = max(5, min(50, calcSteps)).toInt();

    tester.sleep = ProgressValue(max: steps, value: 0);
    var sleepMillis = duration.inMilliseconds ~/ steps;
    var canceled = false;

    var cancelListener = cancelStream?.listen((_) {
      canceled = true;
    });
    try {
      String buildString(int count) {
        var str = '[';
        for (var i = 0; i < count; i++) {
          str += String.fromCharCode(0x2588);
        }
        for (var i = count; i < steps; i++) {
          str += '_';
        }

        str += ']';
        return str;
      }

      if (message?.isNotEmpty == true) {
        _console(message, Level.FINEST);
      } else {
        _console(
          'Sleeping for ${duration.inMilliseconds} millis...',
          Level.FINEST,
        );
      }

      for (var i = 0; i < steps; i++) {
        _console(buildString(i), Level.FINEST);
        tester.sleep = ProgressValue(
          error: error,
          max: steps,
          value: i,
        );
        await Future.delayed(Duration(milliseconds: sleepMillis));

        if (canceled == true) {
          break;
        }
      }
      _console(buildString(steps), Level.FINEST);
    } finally {
      tester.sleep = ProgressValue(
        error: error,
        max: steps,
        value: steps,
      );
      await Future.delayed(Duration(milliseconds: 100));
      tester.sleep = null;
      await cancelListener?.cancel();
    }
  }
}