diff --git a/packages/mason_logger/lib/src/progress.dart b/packages/mason_logger/lib/src/progress.dart index ac80baff..3c1c1369 100644 --- a/packages/mason_logger/lib/src/progress.dart +++ b/packages/mason_logger/lib/src/progress.dart @@ -24,7 +24,12 @@ class ProgressOptions { /// {@endtemplate} class ProgressAnimation { /// {@macro progress_animation} - const ProgressAnimation({this.frames = _defaultFrames}); + const ProgressAnimation({ + this.frames = _defaultFrames, + this.interval = _defaultInterval, + }); + + static const _defaultInterval = Duration(milliseconds: 80); static const _defaultFrames = [ '⠋', @@ -41,6 +46,11 @@ class ProgressAnimation { /// The list of animation frames. final List frames; + + /// The interval at which new frames are produced. + /// In other words, the amount of time spent showing a single frame. + /// Defaults to 80ms per frame. + final Duration interval; } /// {@template progress} @@ -69,7 +79,7 @@ class Progress { return; } - _timer = Timer.periodic(const Duration(milliseconds: 80), _onTick); + _timer = Timer.periodic(options.animation.interval, _onTick); } static const _padding = 15; diff --git a/packages/mason_logger/test/src/progress_test.dart b/packages/mason_logger/test/src/progress_test.dart index 414fd655..a05be530 100644 --- a/packages/mason_logger/test/src/progress_test.dart +++ b/packages/mason_logger/test/src/progress_test.dart @@ -192,6 +192,37 @@ void main() { ); }); + test('writes custom progress interval to stdout', () async { + await _runZoned( + () async { + const time = '(0.Xs)'; + const message = 'test message'; + const progressOptions = ProgressOptions( + animation: ProgressAnimation(interval: Duration(milliseconds: 400)), + ); + final done = Logger().progress(message, options: progressOptions); + await Future.delayed(const Duration(milliseconds: 400)); + done.complete(); + verifyInOrder([ + () { + stdout.write( + '''${lightGreen.wrap('\b${'\b' * (message.length + 4 + time.length)}⠋')} $message... ${darkGray.wrap('(0.1s)')}''', + ); + }, + () { + stdout.write( + '''\b${'\b' * (message.length + 4 + time.length)}\u001b[2K${lightGreen.wrap('✓')} $message ${darkGray.wrap('(0.4s)')}\n''', + ); + }, + ]); + verifyNever(() => stdout.write(any(that: contains('0.2s')))); + verifyNever(() => stdout.write(any(that: contains('0.3s')))); + }, + stdout: () => stdout, + stdin: () => stdin, + ); + }); + test('supports empty list of animation frames', () async { await _runZoned( () async {