diff --git a/lib/audio_handler.dart b/lib/audio_handler.dart index 7534b2d3..fd023b01 100644 --- a/lib/audio_handler.dart +++ b/lib/audio_handler.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:app/app_state.dart'; @@ -13,19 +14,34 @@ import 'package:collection/collection.dart'; import 'package:just_audio/just_audio.dart'; class KoelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { - static const MAX_ERROR_COUNT = 10; + /// How many songs in a row may fail before playback gives up rather than + /// keep skipping. Low, because the common cause of a run of failures is a + /// dead connection, and each skip costs the user their place in the queue. + static const MAX_ERROR_COUNT = 3; late final DownloadProvider downloadProvider; late final PlayableProvider playableProvider; late AudioServiceRepeatMode repeatMode; + /// How long a source is given to become playable before we give up on it. + /// Without this, a stalled connection leaves the player in `loading` + /// indefinitely: neither just_audio nor the platform player time out on + /// their own, so the future never completes and never throws. + final Duration sourceLoadTimeout; + var _errorCount = 0; var _initialized = false; var _currentMediaItem = MediaItem(id: '', title: ''); var _isRadioMode = false; + var _playbackFailed = false; AudioPlayer? _radioPlayer; - final _player = AudioPlayer(); + final AudioPlayer _player; + + KoelAudioHandler({ + AudioPlayer? player, + this.sourceLoadTimeout = const Duration(seconds: 30), + }) : _player = player ?? AudioPlayer(); AudioPlayer get player => _player; @@ -88,58 +104,75 @@ class KoelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { } void _subscribeToPlayerPlaybackEvents() { - _player.playbackEventStream.listen((PlaybackEvent event) { - if (_isRadioMode) return; - final playing = _player.playing; - playbackState.add(playbackState.value.copyWith( - controls: [ - MediaControl.skipToPrevious, - if (playing) MediaControl.pause else MediaControl.play, - MediaControl.stop, - MediaControl.skipToNext, - ], - systemActions: const { - MediaAction.seek, - }, - androidCompactActionIndices: const [0, 1, 3], - processingState: { - // iOS 16+ seems to treat "idle" as "stopped" and close the audio - // session, so we use "ready" to keep it alive. - // @see https://stackoverflow.com/a/75236414 - ProcessingState.idle: Platform.isIOS - ? AudioProcessingState.ready - : AudioProcessingState.idle, - ProcessingState.loading: AudioProcessingState.loading, - ProcessingState.buffering: AudioProcessingState.buffering, - ProcessingState.ready: AudioProcessingState.ready, - ProcessingState.completed: AudioProcessingState.completed, - }[_player.processingState]!, - repeatMode: repeatMode, - shuffleMode: _player.shuffleModeEnabled - ? AudioServiceShuffleMode.all - : AudioServiceShuffleMode.none, - playing: playing, - updatePosition: _player.position, - bufferedPosition: _player.bufferedPosition, - speed: _player.speed, - queueIndex: currentQueueIndex, - )); - }); + _player.playbackEventStream.listen( + (_) => _emitPlaybackState(), + onError: (_, __) => _abandonSource(), + ); + } + + AudioProcessingState get _processingState { + if (_playbackFailed) return AudioProcessingState.error; + + return { + // iOS 16+ seems to treat "idle" as "stopped" and close the audio + // session, so we use "ready" to keep it alive. + // @see https://stackoverflow.com/a/75236414 + ProcessingState.idle: Platform.isIOS + ? AudioProcessingState.ready + : AudioProcessingState.idle, + ProcessingState.loading: AudioProcessingState.loading, + ProcessingState.buffering: AudioProcessingState.buffering, + ProcessingState.ready: AudioProcessingState.ready, + ProcessingState.completed: AudioProcessingState.completed, + }[_player.processingState]!; + } + + void _emitPlaybackState() { + if (_isRadioMode) return; + final playing = _player.playing; + + playbackState.add(playbackState.value.copyWith( + controls: [ + MediaControl.skipToPrevious, + if (playing) MediaControl.pause else MediaControl.play, + MediaControl.stop, + MediaControl.skipToNext, + ], + systemActions: const { + MediaAction.seek, + }, + androidCompactActionIndices: const [0, 1, 3], + processingState: _processingState, + repeatMode: repeatMode, + shuffleMode: _player.shuffleModeEnabled + ? AudioServiceShuffleMode.all + : AudioServiceShuffleMode.none, + playing: playing, + updatePosition: _player.position, + bufferedPosition: _player.bufferedPosition, + speed: _player.speed, + queueIndex: currentQueueIndex, + )); } void _subscribeToPlayerProcessingStateEvents() { - _player.processingStateStream.listen((state) async { - if (_isRadioMode) return; - if (state == ProcessingState.completed) { - if (repeatMode == AudioServiceRepeatMode.one) { - await _player.seek(Duration.zero); - await _player.play(); - return; + _player.processingStateStream.listen( + (state) async { + if (_isRadioMode) return; + if (state == ProcessingState.completed) { + if (repeatMode == AudioServiceRepeatMode.one) { + await _player.seek(Duration.zero); + await _player.play(); + return; + } + + await skipToNext(); } - - await skipToNext(); - } - }); + }, + // This stream is derived from the playback event stream, so it relays the + // same errors. They are already turned into an error state there. + onError: (_, __) {}, + ); } void _trySetUpQueue() async { @@ -160,8 +193,12 @@ class KoelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { ); if (queuedMediaItem != null) { - _setPlayerSource(queuedMediaItem); - player.seek(Duration(seconds: state.playbackPosition)); + try { + await _setPlayerSource(queuedMediaItem).timeout(sourceLoadTimeout); + await player.seek(Duration(seconds: state.playbackPosition)); + } catch (_) { + await _abandonSource(); + } } } @@ -202,6 +239,7 @@ class KoelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { } _setPlayerSource(MediaItem mediaItem) async { + _playbackFailed = false; _currentMediaItem = mediaItem; this.mediaItem.add(_currentMediaItem); @@ -209,19 +247,33 @@ class KoelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { final download = downloadProvider.getForPlayable(playable); if (download == null) { - final uri = Uri.parse(mediaItem.extras?['sourceUrl'] as String); - await _player.setAudioSource(LockCachingAudioSource(uri)); + await _player.setUrl(mediaItem.extras?['sourceUrl'] as String); } else { await _player.setFilePath(download.path); } } + /// Tear down a source that stalled or errored, so the player is left in a + /// state the user can retry or skip out of instead of a permanent spinner. + Future _abandonSource() async { + _playbackFailed = true; + await _player.stop(); + _emitPlaybackState(); + } + @override Future play() async { if (_isRadioMode && _radioPlayer != null) { await _radioPlayer!.play(); return; } + + // The player holds no usable source after a failed load, so pressing play + // has to start the current item over rather than resume it. + if (_playbackFailed && currentQueueIndex > -1) { + return _playAtIndex(currentQueueIndex); + } + playbackState.add(playbackState.value.copyWith(playing: true)); await _player.play(); } @@ -302,23 +354,32 @@ class KoelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { final position = getPlaybackPositionFromState(mediaItem.id) ?? 0; try { - await _setPlayerSource(mediaItem); + await _setPlayerSource(mediaItem).timeout(sourceLoadTimeout); + _errorCount = 0; exitRadioMode(); - _player.seek(Duration(seconds: position.toInt())); + await _player.seek(Duration(seconds: position.toInt())); await play(); + _emitPlaybackState(); put('queue/playback-status', data: { 'song': mediaItem.id, 'position': _player.position.inSeconds, }); - - // Reset the error count if the song is successfully loaded. - _errorCount = 0; - } catch (e) { + } catch (error) { _errorCount++; + await _abandonSource(); + + if (_shouldSkipPast(error)) await skipToNext(); } } + /// A stalled load means the connection is at fault, not the song, and the + /// next one would stall just the same. Every other failure belongs to this + /// song alone, so move past it — but a run of them is something systematic + /// that churning through the queue would only hide. + bool _shouldSkipPast(Object error) => + error is! TimeoutException && _errorCount < MAX_ERROR_COUNT; + @override Future seek(Duration position) => _player.seek(position); diff --git a/lib/ui/widgets/mini_player.dart b/lib/ui/widgets/mini_player.dart index f24a3531..954c79b0 100644 --- a/lib/ui/widgets/mini_player.dart +++ b/lib/ui/widgets/mini_player.dart @@ -20,6 +20,7 @@ import 'package:provider/provider.dart'; class MiniPlayer extends StatefulWidget { static Key pauseButtonKey = UniqueKey(); static Key nextButtonKey = UniqueKey(); + static Key playbackErrorIconKey = UniqueKey(); final AppRouter router; @@ -202,15 +203,12 @@ class _MiniPlayerState extends State with StreamSubscriber { if (playable == null || state == null) return SizedBox.shrink(); - late final bool isLoading; - - if ((state.processingState == AudioProcessingState.buffering || - state.processingState == AudioProcessingState.loading) && - state.playing) { - isLoading = true; - } else { - isLoading = false; - } + final isLoading = state.playing && + (state.processingState == AudioProcessingState.buffering || + state.processingState == AudioProcessingState.loading); + final hasFailed = state.processingState == AudioProcessingState.error; + final overlayDimension = + PlayableThumbnail.dimensionForSize(ThumbnailSize.xs); return _buildShell( content: InkWell( @@ -228,12 +226,9 @@ class _MiniPlayerState extends State with StreamSubscriber { playable: playable, ), ), - if (isLoading) + if (isLoading || hasFailed) SizedBox.square( - dimension: - PlayableThumbnail.dimensionForSize( - ThumbnailSize.xs, - ), + dimension: overlayDimension, child: DecoratedBox( decoration: BoxDecoration( borderRadius: BorderRadius.all( @@ -249,13 +244,21 @@ class _MiniPlayerState extends State with StreamSubscriber { ), if (isLoading) SizedBox.square( - dimension: - PlayableThumbnail.dimensionForSize( - ThumbnailSize.xs, - ), + dimension: overlayDimension, child: SpinKitThreeBounce( color: AppColors.white, size: 16), ), + if (hasFailed) + SizedBox.square( + dimension: overlayDimension, + child: Icon( + CupertinoIcons.exclamationmark_triangle_fill, + key: MiniPlayer.playbackErrorIconKey, + semanticLabel: "Couldn't play this song", + color: AppColors.white, + size: 16, + ), + ), ], ), Expanded( diff --git a/test/audio_handler_test.dart b/test/audio_handler_test.dart new file mode 100644 index 00000000..a90f6378 --- /dev/null +++ b/test/audio_handler_test.dart @@ -0,0 +1,230 @@ +import 'dart:async'; + +import 'package:app/audio_handler.dart'; +import 'package:app/models/models.dart'; +import 'package:app/providers/download_provider.dart'; +import 'package:app/providers/playable_provider.dart'; +import 'package:audio_service/audio_service.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'helpers/api_test_setup.dart'; +import 'audio_handler_test.mocks.dart'; + +@GenerateMocks([AudioPlayer, PlayableProvider, DownloadProvider]) +void main() { + late MockAudioPlayer player; + late MockPlayableProvider playableProvider; + late MockDownloadProvider downloadProvider; + late StreamController playbackEvents; + late StreamController processingStates; + late KoelAudioHandler handler; + late CapturingClient client; + + setUpAll(() async => await initApiTestEnvironment()); + + setUp(() async { + playbackEvents = StreamController.broadcast(); + processingStates = StreamController.broadcast(); + + player = MockAudioPlayer(); + when(player.playbackEventStream).thenAnswer((_) => playbackEvents.stream); + when(player.processingStateStream) + .thenAnswer((_) => processingStates.stream); + when(player.processingState).thenReturn(ProcessingState.ready); + when(player.playing).thenReturn(false); + when(player.shuffleModeEnabled).thenReturn(false); + when(player.position).thenReturn(Duration.zero); + when(player.bufferedPosition).thenReturn(Duration.zero); + when(player.speed).thenReturn(1.0); + when(player.setVolume(any)).thenAnswer((_) async {}); + when(player.setFilePath(any)).thenAnswer((_) async => Duration.zero); + when(player.setUrl(any)).thenAnswer((_) async => Duration.zero); + when(player.seek(any)).thenAnswer((_) async {}); + when(player.play()).thenAnswer((_) async {}); + when(player.stop()).thenAnswer((_) async {}); + + playableProvider = MockPlayableProvider(); + downloadProvider = MockDownloadProvider(); + when(downloadProvider.getForPlayable(any)).thenReturn(null); + + handler = KoelAudioHandler( + player: player, + sourceLoadTimeout: const Duration(milliseconds: 50), + ); + + client = CapturingClient(); + client.install(); + setUpApiTest(); + + await handler.init( + playableProvider: playableProvider, + downloadProvider: downloadProvider, + ); + }); + + tearDown(() async { + await playbackEvents.close(); + await processingStates.close(); + tearDownApiTest(); + }); + + Song registerSong() { + final song = Song.fake(); + when(playableProvider.byId(song.id)).thenReturn(song); + return song; + } + + AudioProcessingState currentProcessingState() => + handler.playbackState.value.processingState; + + test('streams a song that has not been downloaded', () async { + final song = registerSong(); + + await handler.replaceQueue([song]); + + verify(player.setUrl(song.sourceUrl)).called(1); + verifyNever(player.setFilePath(any)); + }); + + test('plays a downloaded song from its local file', () async { + final song = registerSong(); + when(downloadProvider.getForPlayable(song)) + .thenReturn(Download(playable: song, path: '/downloads/song.mp3')); + + await handler.replaceQueue([song]); + + verify(player.setFilePath('/downloads/song.mp3')).called(1); + verifyNever(player.setUrl(any)); + }); + + test('gives up on a source that never becomes playable', () async { + final song = registerSong(); + when(player.setUrl(any)).thenAnswer((_) => Completer().future); + + await handler.replaceQueue([song]); + + verify(player.stop()).called(1); + expect(currentProcessingState(), AudioProcessingState.error); + }); + + test('reports a source that fails outright', () async { + final song = registerSong(); + when(player.setUrl(any)).thenThrow(Exception('no route to host')); + + await handler.replaceQueue([song]); + + verify(player.stop()).called(1); + expect(currentProcessingState(), AudioProcessingState.error); + }); + + test('skips past a song the server refuses to serve', () async { + final broken = registerSong(); + final next = registerSong(); + when(player.setUrl(broken.sourceUrl)).thenThrow(Exception('404')); + + await handler.replaceQueue([broken, next]); + + verify(player.setUrl(next.sourceUrl)).called(1); + expect(handler.mediaItem.value?.id, next.id); + expect(currentProcessingState(), isNot(AudioProcessingState.error)); + }); + + test('stays put when the load stalls instead of skipping', () async { + final stalled = registerSong(); + final next = registerSong(); + when(player.setUrl(stalled.sourceUrl)) + .thenAnswer((_) => Completer().future); + + await handler.replaceQueue([stalled, next]); + + verifyNever(player.setUrl(next.sourceUrl)); + expect(handler.mediaItem.value?.id, stalled.id); + expect(currentProcessingState(), AudioProcessingState.error); + }); + + test('gives up once too many songs fail in a row', () async { + final songs = List.generate( + KoelAudioHandler.MAX_ERROR_COUNT + 3, + (_) => registerSong(), + ); + when(player.setUrl(any)).thenThrow(Exception('404')); + + await handler.replaceQueue(songs); + + verify(player.setUrl(any)).called(KoelAudioHandler.MAX_ERROR_COUNT); + expect(currentProcessingState(), AudioProcessingState.error); + }); + + test('stops skipping at the end of the queue', () async { + final broken = registerSong(); + when(player.setUrl(any)).thenThrow(Exception('404')); + + await handler.replaceQueue([broken]); + + expect(currentProcessingState(), AudioProcessingState.error); + }); + + test('a song that plays clears the run of failures', () async { + final songs = List.generate(6, (_) => registerSong()); + when(player.setUrl(any)).thenThrow(Exception('404')); + when(player.setUrl(songs[1].sourceUrl)) + .thenAnswer((_) async => Duration.zero); + + // Fails on the first song, skips onto the second, which plays. + await handler.replaceQueue(songs); + expect(handler.mediaItem.value?.id, songs[1].id); + + // The three that follow get a full budget of their own, rather than + // inheriting the failure that came before the song that played. + await handler.skipToNext(); + + verify(player.setUrl(songs[4].sourceUrl)).called(1); + verifyNever(player.setUrl(songs[5].sourceUrl)); + }); + + test('can still skip to the next song after a stalled load', () async { + final stalled = registerSong(); + final next = registerSong(); + when(player.setUrl(stalled.sourceUrl)) + .thenAnswer((_) => Completer().future); + + await handler.replaceQueue([stalled, next]); + expect(currentProcessingState(), AudioProcessingState.error); + + await handler.skipToNext(); + + verify(player.setUrl(next.sourceUrl)).called(1); + expect(currentProcessingState(), isNot(AudioProcessingState.error)); + }); + + test('play retries the current song after a failed load', () async { + final song = registerSong(); + final firstAttempt = Completer(); + when(player.setUrl(song.sourceUrl)) + .thenAnswer((_) => firstAttempt.future); + + await handler.replaceQueue([song]); + expect(currentProcessingState(), AudioProcessingState.error); + + when(player.setUrl(song.sourceUrl)).thenAnswer((_) async => Duration.zero); + await handler.play(); + + verify(player.setUrl(song.sourceUrl)).called(2); + expect(currentProcessingState(), isNot(AudioProcessingState.error)); + }); + + test('surfaces an error emitted by the player itself', () async { + final song = registerSong(); + await handler.replaceQueue([song]); + expect(currentProcessingState(), isNot(AudioProcessingState.error)); + + playbackEvents.addError(Exception('platform decoding failure')); + await pumpEventQueue(); + + expect(currentProcessingState(), AudioProcessingState.error); + verify(player.stop()).called(1); + }); +} diff --git a/test/audio_handler_test.mocks.dart b/test/audio_handler_test.mocks.dart new file mode 100644 index 00000000..e6c64673 --- /dev/null +++ b/test/audio_handler_test.mocks.dart @@ -0,0 +1,1077 @@ +// Mocks generated by Mockito 5.4.6 from annotations +// in app/test/audio_handler_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:ui' as _i10; + +import 'package:app/enums.dart' as _i9; +import 'package:app/models/models.dart' as _i8; +import 'package:app/providers/providers.dart' as _i7; +import 'package:app/values/values.dart' as _i3; +import 'package:audio_session/audio_session.dart' as _i6; +import 'package:just_audio/just_audio.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i5; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePlaybackEvent_0 extends _i1.SmartFake implements _i2.PlaybackEvent { + _FakePlaybackEvent_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDuration_1 extends _i1.SmartFake implements Duration { + _FakeDuration_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePlayerState_2 extends _i1.SmartFake implements _i2.PlayerState { + _FakePlayerState_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePaginationResult_3 extends _i1.SmartFake + implements _i3.PaginationResult { + _FakePaginationResult_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [AudioPlayer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAudioPlayer extends _i1.Mock implements _i2.AudioPlayer { + MockAudioPlayer() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.PlaybackEvent get playbackEvent => (super.noSuchMethod( + Invocation.getter(#playbackEvent), + returnValue: _FakePlaybackEvent_0( + this, + Invocation.getter(#playbackEvent), + ), + ) as _i2.PlaybackEvent); + + @override + _i4.Stream<_i2.PlaybackEvent> get playbackEventStream => (super.noSuchMethod( + Invocation.getter(#playbackEventStream), + returnValue: _i4.Stream<_i2.PlaybackEvent>.empty(), + ) as _i4.Stream<_i2.PlaybackEvent>); + + @override + _i4.Stream get durationStream => (super.noSuchMethod( + Invocation.getter(#durationStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i2.ProcessingState get processingState => (super.noSuchMethod( + Invocation.getter(#processingState), + returnValue: _i2.ProcessingState.idle, + ) as _i2.ProcessingState); + + @override + _i4.Stream<_i2.ProcessingState> get processingStateStream => + (super.noSuchMethod( + Invocation.getter(#processingStateStream), + returnValue: _i4.Stream<_i2.ProcessingState>.empty(), + ) as _i4.Stream<_i2.ProcessingState>); + + @override + bool get playing => (super.noSuchMethod( + Invocation.getter(#playing), + returnValue: false, + ) as bool); + + @override + _i4.Stream get playingStream => (super.noSuchMethod( + Invocation.getter(#playingStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + double get volume => (super.noSuchMethod( + Invocation.getter(#volume), + returnValue: 0.0, + ) as double); + + @override + _i4.Stream get volumeStream => (super.noSuchMethod( + Invocation.getter(#volumeStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + double get speed => (super.noSuchMethod( + Invocation.getter(#speed), + returnValue: 0.0, + ) as double); + + @override + _i4.Stream get speedStream => (super.noSuchMethod( + Invocation.getter(#speedStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + double get pitch => (super.noSuchMethod( + Invocation.getter(#pitch), + returnValue: 0.0, + ) as double); + + @override + _i4.Stream get pitchStream => (super.noSuchMethod( + Invocation.getter(#pitchStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + bool get skipSilenceEnabled => (super.noSuchMethod( + Invocation.getter(#skipSilenceEnabled), + returnValue: false, + ) as bool); + + @override + _i4.Stream get skipSilenceEnabledStream => (super.noSuchMethod( + Invocation.getter(#skipSilenceEnabledStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + Duration get bufferedPosition => (super.noSuchMethod( + Invocation.getter(#bufferedPosition), + returnValue: _FakeDuration_1( + this, + Invocation.getter(#bufferedPosition), + ), + ) as Duration); + + @override + _i4.Stream get bufferedPositionStream => (super.noSuchMethod( + Invocation.getter(#bufferedPositionStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream<_i2.IcyMetadata?> get icyMetadataStream => (super.noSuchMethod( + Invocation.getter(#icyMetadataStream), + returnValue: _i4.Stream<_i2.IcyMetadata?>.empty(), + ) as _i4.Stream<_i2.IcyMetadata?>); + + @override + _i2.PlayerState get playerState => (super.noSuchMethod( + Invocation.getter(#playerState), + returnValue: _FakePlayerState_2( + this, + Invocation.getter(#playerState), + ), + ) as _i2.PlayerState); + + @override + _i4.Stream<_i2.PlayerState> get playerStateStream => (super.noSuchMethod( + Invocation.getter(#playerStateStream), + returnValue: _i4.Stream<_i2.PlayerState>.empty(), + ) as _i4.Stream<_i2.PlayerState>); + + @override + _i4.Stream?> get sequenceStream => + (super.noSuchMethod( + Invocation.getter(#sequenceStream), + returnValue: _i4.Stream?>.empty(), + ) as _i4.Stream?>); + + @override + _i4.Stream?> get shuffleIndicesStream => (super.noSuchMethod( + Invocation.getter(#shuffleIndicesStream), + returnValue: _i4.Stream?>.empty(), + ) as _i4.Stream?>); + + @override + _i4.Stream get currentIndexStream => (super.noSuchMethod( + Invocation.getter(#currentIndexStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream<_i2.SequenceState?> get sequenceStateStream => (super.noSuchMethod( + Invocation.getter(#sequenceStateStream), + returnValue: _i4.Stream<_i2.SequenceState?>.empty(), + ) as _i4.Stream<_i2.SequenceState?>); + + @override + bool get hasNext => (super.noSuchMethod( + Invocation.getter(#hasNext), + returnValue: false, + ) as bool); + + @override + bool get hasPrevious => (super.noSuchMethod( + Invocation.getter(#hasPrevious), + returnValue: false, + ) as bool); + + @override + _i2.LoopMode get loopMode => (super.noSuchMethod( + Invocation.getter(#loopMode), + returnValue: _i2.LoopMode.off, + ) as _i2.LoopMode); + + @override + _i4.Stream<_i2.LoopMode> get loopModeStream => (super.noSuchMethod( + Invocation.getter(#loopModeStream), + returnValue: _i4.Stream<_i2.LoopMode>.empty(), + ) as _i4.Stream<_i2.LoopMode>); + + @override + bool get shuffleModeEnabled => (super.noSuchMethod( + Invocation.getter(#shuffleModeEnabled), + returnValue: false, + ) as bool); + + @override + _i4.Stream get shuffleModeEnabledStream => (super.noSuchMethod( + Invocation.getter(#shuffleModeEnabledStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream get androidAudioSessionIdStream => (super.noSuchMethod( + Invocation.getter(#androidAudioSessionIdStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream<_i2.PositionDiscontinuity> get positionDiscontinuityStream => + (super.noSuchMethod( + Invocation.getter(#positionDiscontinuityStream), + returnValue: _i4.Stream<_i2.PositionDiscontinuity>.empty(), + ) as _i4.Stream<_i2.PositionDiscontinuity>); + + @override + bool get automaticallyWaitsToMinimizeStalling => (super.noSuchMethod( + Invocation.getter(#automaticallyWaitsToMinimizeStalling), + returnValue: false, + ) as bool); + + @override + bool get canUseNetworkResourcesForLiveStreamingWhilePaused => + (super.noSuchMethod( + Invocation.getter(#canUseNetworkResourcesForLiveStreamingWhilePaused), + returnValue: false, + ) as bool); + + @override + double get preferredPeakBitRate => (super.noSuchMethod( + Invocation.getter(#preferredPeakBitRate), + returnValue: 0.0, + ) as double); + + @override + bool get allowsExternalPlayback => (super.noSuchMethod( + Invocation.getter(#allowsExternalPlayback), + returnValue: false, + ) as bool); + + @override + String get webSinkId => (super.noSuchMethod( + Invocation.getter(#webSinkId), + returnValue: _i5.dummyValue( + this, + Invocation.getter(#webSinkId), + ), + ) as String); + + @override + Duration get position => (super.noSuchMethod( + Invocation.getter(#position), + returnValue: _FakeDuration_1( + this, + Invocation.getter(#position), + ), + ) as Duration); + + @override + _i4.Stream get positionStream => (super.noSuchMethod( + Invocation.getter(#positionStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream createPositionStream({ + int? steps = 800, + Duration? minPeriod = const Duration(milliseconds: 200), + Duration? maxPeriod = const Duration(milliseconds: 200), + }) => + (super.noSuchMethod( + Invocation.method( + #createPositionStream, + [], + { + #steps: steps, + #minPeriod: minPeriod, + #maxPeriod: maxPeriod, + }, + ), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Future setUrl( + String? url, { + Map? headers, + Duration? initialPosition, + bool? preload = true, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setUrl, + [url], + { + #headers: headers, + #initialPosition: initialPosition, + #preload: preload, + #tag: tag, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setFilePath( + String? filePath, { + Duration? initialPosition, + bool? preload = true, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setFilePath, + [filePath], + { + #initialPosition: initialPosition, + #preload: preload, + #tag: tag, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setAsset( + String? assetPath, { + String? package, + bool? preload = true, + Duration? initialPosition, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setAsset, + [assetPath], + { + #package: package, + #preload: preload, + #initialPosition: initialPosition, + #tag: tag, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setAudioSource( + _i2.AudioSource? source, { + bool? preload = true, + int? initialIndex, + Duration? initialPosition, + }) => + (super.noSuchMethod( + Invocation.method( + #setAudioSource, + [source], + { + #preload: preload, + #initialIndex: initialIndex, + #initialPosition: initialPosition, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future load() => (super.noSuchMethod( + Invocation.method( + #load, + [], + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setClip({ + Duration? start, + Duration? end, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setClip, + [], + { + #start: start, + #end: end, + #tag: tag, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future play() => (super.noSuchMethod( + Invocation.method( + #play, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future stop() => (super.noSuchMethod( + Invocation.method( + #stop, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setVolume(double? volume) => (super.noSuchMethod( + Invocation.method( + #setVolume, + [volume], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setSkipSilenceEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setSkipSilenceEnabled, + [enabled], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setSpeed(double? speed) => (super.noSuchMethod( + Invocation.method( + #setSpeed, + [speed], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setPitch(double? pitch) => (super.noSuchMethod( + Invocation.method( + #setPitch, + [pitch], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setLoopMode(_i2.LoopMode? mode) => (super.noSuchMethod( + Invocation.method( + #setLoopMode, + [mode], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setShuffleModeEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setShuffleModeEnabled, + [enabled], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future shuffle() => (super.noSuchMethod( + Invocation.method( + #shuffle, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setAutomaticallyWaitsToMinimizeStalling( + bool? automaticallyWaitsToMinimizeStalling) => + (super.noSuchMethod( + Invocation.method( + #setAutomaticallyWaitsToMinimizeStalling, + [automaticallyWaitsToMinimizeStalling], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setCanUseNetworkResourcesForLiveStreamingWhilePaused( + bool? canUseNetworkResourcesForLiveStreamingWhilePaused) => + (super.noSuchMethod( + Invocation.method( + #setCanUseNetworkResourcesForLiveStreamingWhilePaused, + [canUseNetworkResourcesForLiveStreamingWhilePaused], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setPreferredPeakBitRate(double? preferredPeakBitRate) => + (super.noSuchMethod( + Invocation.method( + #setPreferredPeakBitRate, + [preferredPeakBitRate], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setAllowsExternalPlayback(bool? allowsExternalPlayback) => + (super.noSuchMethod( + Invocation.method( + #setAllowsExternalPlayback, + [allowsExternalPlayback], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future seek( + Duration? position, { + int? index, + }) => + (super.noSuchMethod( + Invocation.method( + #seek, + [position], + {#index: index}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future seekToNext() => (super.noSuchMethod( + Invocation.method( + #seekToNext, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future seekToPrevious() => (super.noSuchMethod( + Invocation.method( + #seekToPrevious, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setAndroidAudioAttributes( + _i6.AndroidAudioAttributes? audioAttributes) => + (super.noSuchMethod( + Invocation.method( + #setAndroidAudioAttributes, + [audioAttributes], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setWebCrossOrigin(_i2.WebCrossOrigin? webCrossOrigin) => + (super.noSuchMethod( + Invocation.method( + #setWebCrossOrigin, + [webCrossOrigin], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setWebSinkId(String? webSinkId) => (super.noSuchMethod( + Invocation.method( + #setWebSinkId, + [webSinkId], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} + +/// A class which mocks [PlayableProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPlayableProvider extends _i1.Mock implements _i7.PlayableProvider { + MockPlayableProvider() { + _i1.throwOnMissingStub(this); + } + + @override + List<_i8.Playable> get playables => (super.noSuchMethod( + Invocation.getter(#playables), + returnValue: <_i8.Playable>[], + ) as List<_i8.Playable>); + + @override + set playables(List<_i8.Playable>? _playables) => super.noSuchMethod( + Invocation.setter( + #playables, + _playables, + ), + returnValueForMissingStub: null, + ); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + ) as bool); + + @override + List<_i8.Playable> syncWithVault(dynamic _playables) => + (super.noSuchMethod( + Invocation.method( + #syncWithVault, + [_playables], + ), + returnValue: <_i8.Playable>[], + ) as List<_i8.Playable>); + + @override + _i8.Playable? byId(String? id) => + (super.noSuchMethod(Invocation.method( + #byId, + [id], + )) as _i8.Playable?); + + @override + _i4.Future<_i3.PaginationResult<_i8.Playable>> paginate( + _i7.PlayablePaginationConfig? config) => + (super.noSuchMethod( + Invocation.method( + #paginate, + [config], + ), + returnValue: + _i4.Future<_i3.PaginationResult<_i8.Playable>>.value( + _FakePaginationResult_3<_i8.Playable>( + this, + Invocation.method( + #paginate, + [config], + ), + )), + ) as _i4.Future<_i3.PaginationResult<_i8.Playable>>); + + @override + _i4.Future>> fetchForArtist( + dynamic artistId, { + bool? forceRefresh = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForArtist, + [artistId], + {#forceRefresh: forceRefresh}, + ), + returnValue: _i4.Future>>.value( + <_i8.Playable>[]), + ) as _i4.Future>>); + + @override + _i4.Future<_i3.PaginationResult<_i8.Playable>> paginateByGenre( + String? genreId, { + int? page = 1, + String? sort = 'title', + _i9.SortOrder? order = _i9.SortOrder.asc, + }) => + (super.noSuchMethod( + Invocation.method( + #paginateByGenre, + [genreId], + { + #page: page, + #sort: sort, + #order: order, + }, + ), + returnValue: + _i4.Future<_i3.PaginationResult<_i8.Playable>>.value( + _FakePaginationResult_3<_i8.Playable>( + this, + Invocation.method( + #paginateByGenre, + [genreId], + { + #page: page, + #sort: sort, + #order: order, + }, + ), + )), + ) as _i4.Future<_i3.PaginationResult<_i8.Playable>>); + + @override + _i4.Future>> fetchForAlbum( + dynamic albumId, { + bool? forceRefresh = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForAlbum, + [albumId], + {#forceRefresh: forceRefresh}, + ), + returnValue: _i4.Future>>.value( + <_i8.Playable>[]), + ) as _i4.Future>>); + + @override + _i4.Future>> fetchForPlaylist( + dynamic playlistId, { + bool? forceRefresh = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForPlaylist, + [playlistId], + {#forceRefresh: forceRefresh}, + ), + returnValue: _i4.Future>>.value( + <_i8.Playable>[]), + ) as _i4.Future>>); + + @override + _i4.Future>> fetchForPodcast( + String? podcastId, { + bool? forceRefresh = false, + bool? getUpdates = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForPodcast, + [podcastId], + { + #forceRefresh: forceRefresh, + #getUpdates: getUpdates, + }, + ), + returnValue: _i4.Future>>.value( + <_i8.Playable>[]), + ) as _i4.Future>>); + + @override + _i4.Future>> fetchRandom({int? limit = 500}) => + (super.noSuchMethod( + Invocation.method( + #fetchRandom, + [], + {#limit: limit}, + ), + returnValue: _i4.Future>>.value( + <_i8.Playable>[]), + ) as _i4.Future>>); + + @override + _i4.Future>> fetchInOrder({ + String? sortField = 'title', + _i9.SortOrder? order = _i9.SortOrder.asc, + int? limit = 500, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchInOrder, + [], + { + #sortField: sortField, + #order: order, + #limit: limit, + }, + ), + returnValue: _i4.Future>>.value( + <_i8.Playable>[]), + ) as _i4.Future>>); + + @override + List<_i8.Playable> parseFromJson(dynamic json) => + (super.noSuchMethod( + Invocation.method( + #parseFromJson, + [json], + ), + returnValue: <_i8.Playable>[], + ) as List<_i8.Playable>); + + @override + void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void unsubscribeAll() => super.noSuchMethod( + Invocation.method( + #unsubscribeAll, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void subscribe(_i4.StreamSubscription? sub) => super.noSuchMethod( + Invocation.method( + #subscribe, + [sub], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [DownloadProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockDownloadProvider extends _i1.Mock implements _i7.DownloadProvider { + MockDownloadProvider() { + _i1.throwOnMissingStub(this); + } + + @override + List<_i8.Playable> get playables => (super.noSuchMethod( + Invocation.getter(#playables), + returnValue: <_i8.Playable>[], + ) as List<_i8.Playable>); + + @override + _i4.Stream get downloadsClearedStream => (super.noSuchMethod( + Invocation.getter(#downloadsClearedStream), + returnValue: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream<_i8.Playable> get downloadRemovedStream => + (super.noSuchMethod( + Invocation.getter(#downloadRemovedStream), + returnValue: _i4.Stream<_i8.Playable>.empty(), + ) as _i4.Stream<_i8.Playable>); + + @override + _i4.Stream<_i7.Download> get playableDownloadedStream => (super.noSuchMethod( + Invocation.getter(#playableDownloadedStream), + returnValue: _i4.Stream<_i7.Download>.empty(), + ) as _i4.Stream<_i7.Download>); + + @override + _i4.Future get downloadsDir => (super.noSuchMethod( + Invocation.getter(#downloadsDir), + returnValue: _i4.Future.value(_i5.dummyValue( + this, + Invocation.getter(#downloadsDir), + )), + ) as _i4.Future); + + @override + _i4.Future download({required _i8.Playable? playable}) => + (super.noSuchMethod( + Invocation.method( + #download, + [], + {#playable: playable}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i7.Download? getForPlayable(_i8.Playable? playable) => + (super.noSuchMethod(Invocation.method( + #getForPlayable, + [playable], + )) as _i7.Download?); + + @override + bool has({required _i8.Playable? playable}) => (super.noSuchMethod( + Invocation.method( + #has, + [], + {#playable: playable}, + ), + returnValue: false, + ) as bool); + + @override + void persistMetadata() => super.noSuchMethod( + Invocation.method( + #persistMetadata, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void persistMetadataIfNeeded(_i8.Playable? playable) => + super.noSuchMethod( + Invocation.method( + #persistMetadataIfNeeded, + [playable], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future removeForPlayable(_i8.Playable? playable) => + (super.noSuchMethod( + Invocation.method( + #removeForPlayable, + [playable], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future clear() => (super.noSuchMethod( + Invocation.method( + #clear, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void unsubscribeAll() => super.noSuchMethod( + Invocation.method( + #unsubscribeAll, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void subscribe(_i4.StreamSubscription? sub) => super.noSuchMethod( + Invocation.method( + #subscribe, + [sub], + ), + returnValueForMissingStub: null, + ); +} diff --git a/test/ui/screens/album_action_sheet_test.mocks.dart b/test/ui/screens/album_action_sheet_test.mocks.dart index 31cae13b..621308de 100644 --- a/test/ui/screens/album_action_sheet_test.mocks.dart +++ b/test/ui/screens/album_action_sheet_test.mocks.dart @@ -53,8 +53,8 @@ class _FakePlayableProvider_1 extends _i1.SmartFake ); } -class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { - _FakeAudioPlayer_2( +class _FakeDuration_2 extends _i1.SmartFake implements Duration { + _FakeDuration_2( Object parent, Invocation parentInvocation, ) : super( @@ -63,9 +63,19 @@ class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { ); } -class _FakeBehaviorSubject_3 extends _i1.SmartFake +class _FakeAudioPlayer_3 extends _i1.SmartFake implements _i3.AudioPlayer { + _FakeAudioPlayer_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBehaviorSubject_4 extends _i1.SmartFake implements _i4.BehaviorSubject { - _FakeBehaviorSubject_3( + _FakeBehaviorSubject_4( Object parent, Invocation parentInvocation, ) : super( @@ -74,9 +84,9 @@ class _FakeBehaviorSubject_3 extends _i1.SmartFake ); } -class _FakePublishSubject_4 extends _i1.SmartFake +class _FakePublishSubject_5 extends _i1.SmartFake implements _i4.PublishSubject { - _FakePublishSubject_4( + _FakePublishSubject_5( Object parent, Invocation parentInvocation, ) : super( @@ -85,9 +95,9 @@ class _FakePublishSubject_4 extends _i1.SmartFake ); } -class _FakeValueStream_5 extends _i1.SmartFake +class _FakeValueStream_6 extends _i1.SmartFake implements _i4.ValueStream { - _FakeValueStream_5( + _FakeValueStream_6( Object parent, Invocation parentInvocation, ) : super( @@ -96,8 +106,8 @@ class _FakeValueStream_5 extends _i1.SmartFake ); } -class _FakeAlbum_6 extends _i1.SmartFake implements _i5.Album { - _FakeAlbum_6( +class _FakeAlbum_7 extends _i1.SmartFake implements _i5.Album { + _FakeAlbum_7( Object parent, Invocation parentInvocation, ) : super( @@ -106,9 +116,9 @@ class _FakeAlbum_6 extends _i1.SmartFake implements _i5.Album { ); } -class _FakePaginationResult_7 extends _i1.SmartFake +class _FakePaginationResult_8 extends _i1.SmartFake implements _i6.PaginationResult { - _FakePaginationResult_7( + _FakePaginationResult_8( Object parent, Invocation parentInvocation, ) : super( @@ -149,10 +159,19 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { returnValue: _i8.AudioServiceRepeatMode.none, ) as _i8.AudioServiceRepeatMode); + @override + Duration get sourceLoadTimeout => (super.noSuchMethod( + Invocation.getter(#sourceLoadTimeout), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#sourceLoadTimeout), + ), + ) as Duration); + @override _i3.AudioPlayer get player => (super.noSuchMethod( Invocation.getter(#player), - returnValue: _FakeAudioPlayer_2( + returnValue: _FakeAudioPlayer_3( this, Invocation.getter(#player), ), @@ -203,7 +222,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { _i4.BehaviorSubject<_i8.PlaybackState> get playbackState => (super.noSuchMethod( Invocation.getter(#playbackState), - returnValue: _FakeBehaviorSubject_3<_i8.PlaybackState>( + returnValue: _FakeBehaviorSubject_4<_i8.PlaybackState>( this, Invocation.getter(#playbackState), ), @@ -212,7 +231,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject> get queue => (super.noSuchMethod( Invocation.getter(#queue), - returnValue: _FakeBehaviorSubject_3>( + returnValue: _FakeBehaviorSubject_4>( this, Invocation.getter(#queue), ), @@ -221,7 +240,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject get queueTitle => (super.noSuchMethod( Invocation.getter(#queueTitle), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#queueTitle), ), @@ -230,7 +249,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject<_i8.MediaItem?> get mediaItem => (super.noSuchMethod( Invocation.getter(#mediaItem), - returnValue: _FakeBehaviorSubject_3<_i8.MediaItem?>( + returnValue: _FakeBehaviorSubject_4<_i8.MediaItem?>( this, Invocation.getter(#mediaItem), ), @@ -240,7 +259,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { _i4.BehaviorSubject<_i8.AndroidPlaybackInfo> get androidPlaybackInfo => (super.noSuchMethod( Invocation.getter(#androidPlaybackInfo), - returnValue: _FakeBehaviorSubject_3<_i8.AndroidPlaybackInfo>( + returnValue: _FakeBehaviorSubject_4<_i8.AndroidPlaybackInfo>( this, Invocation.getter(#androidPlaybackInfo), ), @@ -249,7 +268,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject<_i8.RatingStyle> get ratingStyle => (super.noSuchMethod( Invocation.getter(#ratingStyle), - returnValue: _FakeBehaviorSubject_3<_i8.RatingStyle>( + returnValue: _FakeBehaviorSubject_4<_i8.RatingStyle>( this, Invocation.getter(#ratingStyle), ), @@ -258,7 +277,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.PublishSubject get customEvent => (super.noSuchMethod( Invocation.getter(#customEvent), - returnValue: _FakePublishSubject_4( + returnValue: _FakePublishSubject_5( this, Invocation.getter(#customEvent), ), @@ -267,7 +286,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject get customState => (super.noSuchMethod( Invocation.getter(#customState), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#customState), ), @@ -945,7 +964,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { #subscribeToChildren, [parentMediaId], ), - returnValue: _FakeValueStream_5>( + returnValue: _FakeValueStream_6>( this, Invocation.method( #subscribeToChildren, @@ -1086,7 +1105,7 @@ class MockAlbumProvider extends _i1.Mock implements _i2.AlbumProvider { [id], {#forceRefresh: forceRefresh}, ), - returnValue: _i9.Future<_i5.Album>.value(_FakeAlbum_6( + returnValue: _i9.Future<_i5.Album>.value(_FakeAlbum_7( this, Invocation.method( #resolve, @@ -1265,7 +1284,7 @@ class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { ), returnValue: _i9.Future<_i6.PaginationResult<_i5.Playable>>.value( - _FakePaginationResult_7<_i5.Playable>( + _FakePaginationResult_8<_i5.Playable>( this, Invocation.method( #paginate, @@ -1308,7 +1327,7 @@ class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { ), returnValue: _i9.Future<_i6.PaginationResult<_i5.Playable>>.value( - _FakePaginationResult_7<_i5.Playable>( + _FakePaginationResult_8<_i5.Playable>( this, Invocation.method( #paginateByGenre, diff --git a/test/ui/screens/artist_action_sheet_test.mocks.dart b/test/ui/screens/artist_action_sheet_test.mocks.dart index d53bcca5..e10b2672 100644 --- a/test/ui/screens/artist_action_sheet_test.mocks.dart +++ b/test/ui/screens/artist_action_sheet_test.mocks.dart @@ -53,8 +53,8 @@ class _FakePlayableProvider_1 extends _i1.SmartFake ); } -class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { - _FakeAudioPlayer_2( +class _FakeDuration_2 extends _i1.SmartFake implements Duration { + _FakeDuration_2( Object parent, Invocation parentInvocation, ) : super( @@ -63,9 +63,19 @@ class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { ); } -class _FakeBehaviorSubject_3 extends _i1.SmartFake +class _FakeAudioPlayer_3 extends _i1.SmartFake implements _i3.AudioPlayer { + _FakeAudioPlayer_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBehaviorSubject_4 extends _i1.SmartFake implements _i4.BehaviorSubject { - _FakeBehaviorSubject_3( + _FakeBehaviorSubject_4( Object parent, Invocation parentInvocation, ) : super( @@ -74,9 +84,9 @@ class _FakeBehaviorSubject_3 extends _i1.SmartFake ); } -class _FakePublishSubject_4 extends _i1.SmartFake +class _FakePublishSubject_5 extends _i1.SmartFake implements _i4.PublishSubject { - _FakePublishSubject_4( + _FakePublishSubject_5( Object parent, Invocation parentInvocation, ) : super( @@ -85,9 +95,9 @@ class _FakePublishSubject_4 extends _i1.SmartFake ); } -class _FakeValueStream_5 extends _i1.SmartFake +class _FakeValueStream_6 extends _i1.SmartFake implements _i4.ValueStream { - _FakeValueStream_5( + _FakeValueStream_6( Object parent, Invocation parentInvocation, ) : super( @@ -96,8 +106,8 @@ class _FakeValueStream_5 extends _i1.SmartFake ); } -class _FakeArtist_6 extends _i1.SmartFake implements _i5.Artist { - _FakeArtist_6( +class _FakeArtist_7 extends _i1.SmartFake implements _i5.Artist { + _FakeArtist_7( Object parent, Invocation parentInvocation, ) : super( @@ -106,9 +116,9 @@ class _FakeArtist_6 extends _i1.SmartFake implements _i5.Artist { ); } -class _FakePaginationResult_7 extends _i1.SmartFake +class _FakePaginationResult_8 extends _i1.SmartFake implements _i6.PaginationResult { - _FakePaginationResult_7( + _FakePaginationResult_8( Object parent, Invocation parentInvocation, ) : super( @@ -149,10 +159,19 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { returnValue: _i8.AudioServiceRepeatMode.none, ) as _i8.AudioServiceRepeatMode); + @override + Duration get sourceLoadTimeout => (super.noSuchMethod( + Invocation.getter(#sourceLoadTimeout), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#sourceLoadTimeout), + ), + ) as Duration); + @override _i3.AudioPlayer get player => (super.noSuchMethod( Invocation.getter(#player), - returnValue: _FakeAudioPlayer_2( + returnValue: _FakeAudioPlayer_3( this, Invocation.getter(#player), ), @@ -203,7 +222,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { _i4.BehaviorSubject<_i8.PlaybackState> get playbackState => (super.noSuchMethod( Invocation.getter(#playbackState), - returnValue: _FakeBehaviorSubject_3<_i8.PlaybackState>( + returnValue: _FakeBehaviorSubject_4<_i8.PlaybackState>( this, Invocation.getter(#playbackState), ), @@ -212,7 +231,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject> get queue => (super.noSuchMethod( Invocation.getter(#queue), - returnValue: _FakeBehaviorSubject_3>( + returnValue: _FakeBehaviorSubject_4>( this, Invocation.getter(#queue), ), @@ -221,7 +240,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject get queueTitle => (super.noSuchMethod( Invocation.getter(#queueTitle), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#queueTitle), ), @@ -230,7 +249,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject<_i8.MediaItem?> get mediaItem => (super.noSuchMethod( Invocation.getter(#mediaItem), - returnValue: _FakeBehaviorSubject_3<_i8.MediaItem?>( + returnValue: _FakeBehaviorSubject_4<_i8.MediaItem?>( this, Invocation.getter(#mediaItem), ), @@ -240,7 +259,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { _i4.BehaviorSubject<_i8.AndroidPlaybackInfo> get androidPlaybackInfo => (super.noSuchMethod( Invocation.getter(#androidPlaybackInfo), - returnValue: _FakeBehaviorSubject_3<_i8.AndroidPlaybackInfo>( + returnValue: _FakeBehaviorSubject_4<_i8.AndroidPlaybackInfo>( this, Invocation.getter(#androidPlaybackInfo), ), @@ -249,7 +268,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject<_i8.RatingStyle> get ratingStyle => (super.noSuchMethod( Invocation.getter(#ratingStyle), - returnValue: _FakeBehaviorSubject_3<_i8.RatingStyle>( + returnValue: _FakeBehaviorSubject_4<_i8.RatingStyle>( this, Invocation.getter(#ratingStyle), ), @@ -258,7 +277,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.PublishSubject get customEvent => (super.noSuchMethod( Invocation.getter(#customEvent), - returnValue: _FakePublishSubject_4( + returnValue: _FakePublishSubject_5( this, Invocation.getter(#customEvent), ), @@ -267,7 +286,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject get customState => (super.noSuchMethod( Invocation.getter(#customState), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#customState), ), @@ -945,7 +964,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { #subscribeToChildren, [parentMediaId], ), - returnValue: _FakeValueStream_5>( + returnValue: _FakeValueStream_6>( this, Invocation.method( #subscribeToChildren, @@ -1086,7 +1105,7 @@ class MockArtistProvider extends _i1.Mock implements _i2.ArtistProvider { [id], {#forceRefresh: forceRefresh}, ), - returnValue: _i9.Future<_i5.Artist>.value(_FakeArtist_6( + returnValue: _i9.Future<_i5.Artist>.value(_FakeArtist_7( this, Invocation.method( #resolve, @@ -1261,7 +1280,7 @@ class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { ), returnValue: _i9.Future<_i6.PaginationResult<_i5.Playable>>.value( - _FakePaginationResult_7<_i5.Playable>( + _FakePaginationResult_8<_i5.Playable>( this, Invocation.method( #paginate, @@ -1304,7 +1323,7 @@ class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { ), returnValue: _i9.Future<_i6.PaginationResult<_i5.Playable>>.value( - _FakePaginationResult_7<_i5.Playable>( + _FakePaginationResult_8<_i5.Playable>( this, Invocation.method( #paginateByGenre, diff --git a/test/ui/screens/downloaded_test.mocks.dart b/test/ui/screens/downloaded_test.mocks.dart index ce5d9cec..642cfb06 100644 --- a/test/ui/screens/downloaded_test.mocks.dart +++ b/test/ui/screens/downloaded_test.mocks.dart @@ -50,8 +50,8 @@ class _FakePlayableProvider_1 extends _i1.SmartFake ); } -class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { - _FakeAudioPlayer_2( +class _FakeDuration_2 extends _i1.SmartFake implements Duration { + _FakeDuration_2( Object parent, Invocation parentInvocation, ) : super( @@ -60,9 +60,19 @@ class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { ); } -class _FakeBehaviorSubject_3 extends _i1.SmartFake +class _FakeAudioPlayer_3 extends _i1.SmartFake implements _i3.AudioPlayer { + _FakeAudioPlayer_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBehaviorSubject_4 extends _i1.SmartFake implements _i4.BehaviorSubject { - _FakeBehaviorSubject_3( + _FakeBehaviorSubject_4( Object parent, Invocation parentInvocation, ) : super( @@ -71,9 +81,9 @@ class _FakeBehaviorSubject_3 extends _i1.SmartFake ); } -class _FakePublishSubject_4 extends _i1.SmartFake +class _FakePublishSubject_5 extends _i1.SmartFake implements _i4.PublishSubject { - _FakePublishSubject_4( + _FakePublishSubject_5( Object parent, Invocation parentInvocation, ) : super( @@ -82,9 +92,9 @@ class _FakePublishSubject_4 extends _i1.SmartFake ); } -class _FakeValueStream_5 extends _i1.SmartFake +class _FakeValueStream_6 extends _i1.SmartFake implements _i4.ValueStream { - _FakeValueStream_5( + _FakeValueStream_6( Object parent, Invocation parentInvocation, ) : super( @@ -125,10 +135,19 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { returnValue: _i6.AudioServiceRepeatMode.none, ) as _i6.AudioServiceRepeatMode); + @override + Duration get sourceLoadTimeout => (super.noSuchMethod( + Invocation.getter(#sourceLoadTimeout), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#sourceLoadTimeout), + ), + ) as Duration); + @override _i3.AudioPlayer get player => (super.noSuchMethod( Invocation.getter(#player), - returnValue: _FakeAudioPlayer_2( + returnValue: _FakeAudioPlayer_3( this, Invocation.getter(#player), ), @@ -179,7 +198,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { _i4.BehaviorSubject<_i6.PlaybackState> get playbackState => (super.noSuchMethod( Invocation.getter(#playbackState), - returnValue: _FakeBehaviorSubject_3<_i6.PlaybackState>( + returnValue: _FakeBehaviorSubject_4<_i6.PlaybackState>( this, Invocation.getter(#playbackState), ), @@ -188,7 +207,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject> get queue => (super.noSuchMethod( Invocation.getter(#queue), - returnValue: _FakeBehaviorSubject_3>( + returnValue: _FakeBehaviorSubject_4>( this, Invocation.getter(#queue), ), @@ -197,7 +216,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject get queueTitle => (super.noSuchMethod( Invocation.getter(#queueTitle), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#queueTitle), ), @@ -206,7 +225,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject<_i6.MediaItem?> get mediaItem => (super.noSuchMethod( Invocation.getter(#mediaItem), - returnValue: _FakeBehaviorSubject_3<_i6.MediaItem?>( + returnValue: _FakeBehaviorSubject_4<_i6.MediaItem?>( this, Invocation.getter(#mediaItem), ), @@ -216,7 +235,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { _i4.BehaviorSubject<_i6.AndroidPlaybackInfo> get androidPlaybackInfo => (super.noSuchMethod( Invocation.getter(#androidPlaybackInfo), - returnValue: _FakeBehaviorSubject_3<_i6.AndroidPlaybackInfo>( + returnValue: _FakeBehaviorSubject_4<_i6.AndroidPlaybackInfo>( this, Invocation.getter(#androidPlaybackInfo), ), @@ -225,7 +244,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject<_i6.RatingStyle> get ratingStyle => (super.noSuchMethod( Invocation.getter(#ratingStyle), - returnValue: _FakeBehaviorSubject_3<_i6.RatingStyle>( + returnValue: _FakeBehaviorSubject_4<_i6.RatingStyle>( this, Invocation.getter(#ratingStyle), ), @@ -234,7 +253,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.PublishSubject get customEvent => (super.noSuchMethod( Invocation.getter(#customEvent), - returnValue: _FakePublishSubject_4( + returnValue: _FakePublishSubject_5( this, Invocation.getter(#customEvent), ), @@ -243,7 +262,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject get customState => (super.noSuchMethod( Invocation.getter(#customState), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#customState), ), @@ -921,7 +940,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { #subscribeToChildren, [parentMediaId], ), - returnValue: _FakeValueStream_5>( + returnValue: _FakeValueStream_6>( this, Invocation.method( #subscribeToChildren, diff --git a/test/ui/screens/playable_action_sheet_test.mocks.dart b/test/ui/screens/playable_action_sheet_test.mocks.dart index d8450641..49f4ab37 100644 --- a/test/ui/screens/playable_action_sheet_test.mocks.dart +++ b/test/ui/screens/playable_action_sheet_test.mocks.dart @@ -51,8 +51,8 @@ class _FakePlayableProvider_1 extends _i1.SmartFake ); } -class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { - _FakeAudioPlayer_2( +class _FakeDuration_2 extends _i1.SmartFake implements Duration { + _FakeDuration_2( Object parent, Invocation parentInvocation, ) : super( @@ -61,9 +61,19 @@ class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { ); } -class _FakeBehaviorSubject_3 extends _i1.SmartFake +class _FakeAudioPlayer_3 extends _i1.SmartFake implements _i3.AudioPlayer { + _FakeAudioPlayer_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBehaviorSubject_4 extends _i1.SmartFake implements _i4.BehaviorSubject { - _FakeBehaviorSubject_3( + _FakeBehaviorSubject_4( Object parent, Invocation parentInvocation, ) : super( @@ -72,9 +82,9 @@ class _FakeBehaviorSubject_3 extends _i1.SmartFake ); } -class _FakePublishSubject_4 extends _i1.SmartFake +class _FakePublishSubject_5 extends _i1.SmartFake implements _i4.PublishSubject { - _FakePublishSubject_4( + _FakePublishSubject_5( Object parent, Invocation parentInvocation, ) : super( @@ -83,9 +93,9 @@ class _FakePublishSubject_4 extends _i1.SmartFake ); } -class _FakeValueStream_5 extends _i1.SmartFake +class _FakeValueStream_6 extends _i1.SmartFake implements _i4.ValueStream { - _FakeValueStream_5( + _FakeValueStream_6( Object parent, Invocation parentInvocation, ) : super( @@ -126,10 +136,19 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { returnValue: _i6.AudioServiceRepeatMode.none, ) as _i6.AudioServiceRepeatMode); + @override + Duration get sourceLoadTimeout => (super.noSuchMethod( + Invocation.getter(#sourceLoadTimeout), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#sourceLoadTimeout), + ), + ) as Duration); + @override _i3.AudioPlayer get player => (super.noSuchMethod( Invocation.getter(#player), - returnValue: _FakeAudioPlayer_2( + returnValue: _FakeAudioPlayer_3( this, Invocation.getter(#player), ), @@ -180,7 +199,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { _i4.BehaviorSubject<_i6.PlaybackState> get playbackState => (super.noSuchMethod( Invocation.getter(#playbackState), - returnValue: _FakeBehaviorSubject_3<_i6.PlaybackState>( + returnValue: _FakeBehaviorSubject_4<_i6.PlaybackState>( this, Invocation.getter(#playbackState), ), @@ -189,7 +208,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject> get queue => (super.noSuchMethod( Invocation.getter(#queue), - returnValue: _FakeBehaviorSubject_3>( + returnValue: _FakeBehaviorSubject_4>( this, Invocation.getter(#queue), ), @@ -198,7 +217,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject get queueTitle => (super.noSuchMethod( Invocation.getter(#queueTitle), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#queueTitle), ), @@ -207,7 +226,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject<_i6.MediaItem?> get mediaItem => (super.noSuchMethod( Invocation.getter(#mediaItem), - returnValue: _FakeBehaviorSubject_3<_i6.MediaItem?>( + returnValue: _FakeBehaviorSubject_4<_i6.MediaItem?>( this, Invocation.getter(#mediaItem), ), @@ -217,7 +236,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { _i4.BehaviorSubject<_i6.AndroidPlaybackInfo> get androidPlaybackInfo => (super.noSuchMethod( Invocation.getter(#androidPlaybackInfo), - returnValue: _FakeBehaviorSubject_3<_i6.AndroidPlaybackInfo>( + returnValue: _FakeBehaviorSubject_4<_i6.AndroidPlaybackInfo>( this, Invocation.getter(#androidPlaybackInfo), ), @@ -226,7 +245,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject<_i6.RatingStyle> get ratingStyle => (super.noSuchMethod( Invocation.getter(#ratingStyle), - returnValue: _FakeBehaviorSubject_3<_i6.RatingStyle>( + returnValue: _FakeBehaviorSubject_4<_i6.RatingStyle>( this, Invocation.getter(#ratingStyle), ), @@ -235,7 +254,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.PublishSubject get customEvent => (super.noSuchMethod( Invocation.getter(#customEvent), - returnValue: _FakePublishSubject_4( + returnValue: _FakePublishSubject_5( this, Invocation.getter(#customEvent), ), @@ -244,7 +263,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { @override _i4.BehaviorSubject get customState => (super.noSuchMethod( Invocation.getter(#customState), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#customState), ), @@ -922,7 +941,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i5.KoelAudioHandler { #subscribeToChildren, [parentMediaId], ), - returnValue: _FakeValueStream_5>( + returnValue: _FakeValueStream_6>( this, Invocation.method( #subscribeToChildren, diff --git a/test/ui/screens/podcast_action_sheet_test.mocks.dart b/test/ui/screens/podcast_action_sheet_test.mocks.dart index 48362cb4..fdba379c 100644 --- a/test/ui/screens/podcast_action_sheet_test.mocks.dart +++ b/test/ui/screens/podcast_action_sheet_test.mocks.dart @@ -52,8 +52,8 @@ class _FakePlayableProvider_1 extends _i1.SmartFake ); } -class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { - _FakeAudioPlayer_2( +class _FakeDuration_2 extends _i1.SmartFake implements Duration { + _FakeDuration_2( Object parent, Invocation parentInvocation, ) : super( @@ -62,9 +62,19 @@ class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i3.AudioPlayer { ); } -class _FakeBehaviorSubject_3 extends _i1.SmartFake +class _FakeAudioPlayer_3 extends _i1.SmartFake implements _i3.AudioPlayer { + _FakeAudioPlayer_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBehaviorSubject_4 extends _i1.SmartFake implements _i4.BehaviorSubject { - _FakeBehaviorSubject_3( + _FakeBehaviorSubject_4( Object parent, Invocation parentInvocation, ) : super( @@ -73,9 +83,9 @@ class _FakeBehaviorSubject_3 extends _i1.SmartFake ); } -class _FakePublishSubject_4 extends _i1.SmartFake +class _FakePublishSubject_5 extends _i1.SmartFake implements _i4.PublishSubject { - _FakePublishSubject_4( + _FakePublishSubject_5( Object parent, Invocation parentInvocation, ) : super( @@ -84,9 +94,9 @@ class _FakePublishSubject_4 extends _i1.SmartFake ); } -class _FakeValueStream_5 extends _i1.SmartFake +class _FakeValueStream_6 extends _i1.SmartFake implements _i4.ValueStream { - _FakeValueStream_5( + _FakeValueStream_6( Object parent, Invocation parentInvocation, ) : super( @@ -95,8 +105,8 @@ class _FakeValueStream_5 extends _i1.SmartFake ); } -class _FakePodcast_6 extends _i1.SmartFake implements _i5.Podcast { - _FakePodcast_6( +class _FakePodcast_7 extends _i1.SmartFake implements _i5.Podcast { + _FakePodcast_7( Object parent, Invocation parentInvocation, ) : super( @@ -105,9 +115,9 @@ class _FakePodcast_6 extends _i1.SmartFake implements _i5.Podcast { ); } -class _FakePaginationResult_7 extends _i1.SmartFake +class _FakePaginationResult_8 extends _i1.SmartFake implements _i6.PaginationResult { - _FakePaginationResult_7( + _FakePaginationResult_8( Object parent, Invocation parentInvocation, ) : super( @@ -148,10 +158,19 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { returnValue: _i8.AudioServiceRepeatMode.none, ) as _i8.AudioServiceRepeatMode); + @override + Duration get sourceLoadTimeout => (super.noSuchMethod( + Invocation.getter(#sourceLoadTimeout), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#sourceLoadTimeout), + ), + ) as Duration); + @override _i3.AudioPlayer get player => (super.noSuchMethod( Invocation.getter(#player), - returnValue: _FakeAudioPlayer_2( + returnValue: _FakeAudioPlayer_3( this, Invocation.getter(#player), ), @@ -202,7 +221,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { _i4.BehaviorSubject<_i8.PlaybackState> get playbackState => (super.noSuchMethod( Invocation.getter(#playbackState), - returnValue: _FakeBehaviorSubject_3<_i8.PlaybackState>( + returnValue: _FakeBehaviorSubject_4<_i8.PlaybackState>( this, Invocation.getter(#playbackState), ), @@ -211,7 +230,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject> get queue => (super.noSuchMethod( Invocation.getter(#queue), - returnValue: _FakeBehaviorSubject_3>( + returnValue: _FakeBehaviorSubject_4>( this, Invocation.getter(#queue), ), @@ -220,7 +239,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject get queueTitle => (super.noSuchMethod( Invocation.getter(#queueTitle), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#queueTitle), ), @@ -229,7 +248,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject<_i8.MediaItem?> get mediaItem => (super.noSuchMethod( Invocation.getter(#mediaItem), - returnValue: _FakeBehaviorSubject_3<_i8.MediaItem?>( + returnValue: _FakeBehaviorSubject_4<_i8.MediaItem?>( this, Invocation.getter(#mediaItem), ), @@ -239,7 +258,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { _i4.BehaviorSubject<_i8.AndroidPlaybackInfo> get androidPlaybackInfo => (super.noSuchMethod( Invocation.getter(#androidPlaybackInfo), - returnValue: _FakeBehaviorSubject_3<_i8.AndroidPlaybackInfo>( + returnValue: _FakeBehaviorSubject_4<_i8.AndroidPlaybackInfo>( this, Invocation.getter(#androidPlaybackInfo), ), @@ -248,7 +267,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject<_i8.RatingStyle> get ratingStyle => (super.noSuchMethod( Invocation.getter(#ratingStyle), - returnValue: _FakeBehaviorSubject_3<_i8.RatingStyle>( + returnValue: _FakeBehaviorSubject_4<_i8.RatingStyle>( this, Invocation.getter(#ratingStyle), ), @@ -257,7 +276,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.PublishSubject get customEvent => (super.noSuchMethod( Invocation.getter(#customEvent), - returnValue: _FakePublishSubject_4( + returnValue: _FakePublishSubject_5( this, Invocation.getter(#customEvent), ), @@ -266,7 +285,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { @override _i4.BehaviorSubject get customState => (super.noSuchMethod( Invocation.getter(#customState), - returnValue: _FakeBehaviorSubject_3( + returnValue: _FakeBehaviorSubject_4( this, Invocation.getter(#customState), ), @@ -944,7 +963,7 @@ class MockKoelAudioHandler extends _i1.Mock implements _i7.KoelAudioHandler { #subscribeToChildren, [parentMediaId], ), - returnValue: _FakeValueStream_5>( + returnValue: _FakeValueStream_6>( this, Invocation.method( #subscribeToChildren, @@ -1071,7 +1090,7 @@ class MockPodcastProvider extends _i1.Mock implements _i2.PodcastProvider { [], {#url: url}, ), - returnValue: _i9.Future<_i5.Podcast>.value(_FakePodcast_6( + returnValue: _i9.Future<_i5.Podcast>.value(_FakePodcast_7( this, Invocation.method( #add, @@ -1092,7 +1111,7 @@ class MockPodcastProvider extends _i1.Mock implements _i2.PodcastProvider { [id], {#forceRefresh: forceRefresh}, ), - returnValue: _i9.Future<_i5.Podcast>.value(_FakePodcast_6( + returnValue: _i9.Future<_i5.Podcast>.value(_FakePodcast_7( this, Invocation.method( #resolve, @@ -1223,7 +1242,7 @@ class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { ), returnValue: _i9.Future<_i6.PaginationResult<_i5.Playable>>.value( - _FakePaginationResult_7<_i5.Playable>( + _FakePaginationResult_8<_i5.Playable>( this, Invocation.method( #paginate, @@ -1266,7 +1285,7 @@ class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { ), returnValue: _i9.Future<_i6.PaginationResult<_i5.Playable>>.value( - _FakePaginationResult_7<_i5.Playable>( + _FakePaginationResult_8<_i5.Playable>( this, Invocation.method( #paginateByGenre, diff --git a/test/ui/widgets/mini_player_test.dart b/test/ui/widgets/mini_player_test.dart new file mode 100644 index 00000000..c47bed41 --- /dev/null +++ b/test/ui/widgets/mini_player_test.dart @@ -0,0 +1,122 @@ +import 'package:app/audio_handler.dart'; +import 'package:app/main.dart' as app; +import 'package:app/models/song.dart'; +import 'package:app/providers/playable_provider.dart'; +import 'package:app/providers/radio_player_provider.dart'; +import 'package:app/ui/widgets/mini_player.dart'; +import 'package:audio_service/audio_service.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:provider/provider.dart'; +import 'package:rxdart/rxdart.dart'; + +import '../../extensions/widget_tester_extension.dart'; +import 'mini_player_test.mocks.dart'; + +@GenerateMocks([KoelAudioHandler, PlayableProvider, RadioPlayerProvider, AudioPlayer]) +void main() { + late MockKoelAudioHandler audioHandlerMock; + late MockPlayableProvider playableProviderMock; + late MockRadioPlayerProvider radioPlayerProviderMock; + late BehaviorSubject playbackStateSubject; + late BehaviorSubject mediaItemSubject; + late Song song; + + setUp(() { + // Short enough that MarqueeText doesn't need to scroll: its animation + // timers outlive the widget tree and trip the test binding. + song = Song.fake(title: 'Elevation'); + + playbackStateSubject = BehaviorSubject.seeded( + PlaybackState(), + ); + mediaItemSubject = BehaviorSubject.seeded( + MediaItem(id: song.id, title: song.title), + ); + + final playerMock = MockAudioPlayer(); + when(playerMock.positionStream).thenAnswer((_) => Stream.value( + Duration.zero, + )); + + audioHandlerMock = MockKoelAudioHandler(); + when(audioHandlerMock.playbackState).thenAnswer((_) => playbackStateSubject); + when(audioHandlerMock.mediaItem).thenAnswer((_) => mediaItemSubject); + when(audioHandlerMock.player).thenReturn(playerMock); + app.audioHandler = audioHandlerMock; + + playableProviderMock = MockPlayableProvider(); + when(playableProviderMock.byId(song.id)).thenReturn(song); + + radioPlayerProviderMock = MockRadioPlayerProvider(); + when(radioPlayerProviderMock.active).thenReturn(false); + }); + + tearDown(() async { + await playbackStateSubject.close(); + await mediaItemSubject.close(); + }); + + Future pumpWithState( + WidgetTester tester, + PlaybackState state, + ) async { + playbackStateSubject.add(state); + + await tester.pumpAppWidget( + MultiProvider( + providers: [ + ChangeNotifierProvider.value( + value: playableProviderMock, + ), + ChangeNotifierProvider.value( + value: radioPlayerProviderMock, + ), + ], + child: const MiniPlayer(), + ), + ); + await tester.pump(); + } + + final errorIcon = find.byKey(MiniPlayer.playbackErrorIconKey); + + testWidgets('marks a song that failed to load', (tester) async { + await pumpWithState( + tester, + PlaybackState(processingState: AudioProcessingState.error), + ); + + expect(errorIcon, findsOneWidget); + expect(find.byType(SpinKitThreeBounce), findsNothing); + }); + + testWidgets('spins while a song is loading', (tester) async { + await pumpWithState( + tester, + PlaybackState( + processingState: AudioProcessingState.loading, + playing: true, + ), + ); + + expect(find.byType(SpinKitThreeBounce), findsOneWidget); + expect(errorIcon, findsNothing); + }); + + testWidgets('shows no overlay once a song is playing', (tester) async { + await pumpWithState( + tester, + PlaybackState( + processingState: AudioProcessingState.ready, + playing: true, + ), + ); + + expect(errorIcon, findsNothing); + expect(find.byType(SpinKitThreeBounce), findsNothing); + }); +} diff --git a/test/ui/widgets/mini_player_test.mocks.dart b/test/ui/widgets/mini_player_test.mocks.dart new file mode 100644 index 00000000..2334d725 --- /dev/null +++ b/test/ui/widgets/mini_player_test.mocks.dart @@ -0,0 +1,2020 @@ +// Mocks generated by Mockito 5.4.6 from annotations +// in app/test/ui/widgets/mini_player_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i8; +import 'dart:ui' as _i11; + +import 'package:app/audio_handler.dart' as _i6; +import 'package:app/enums.dart' as _i10; +import 'package:app/models/models.dart' as _i9; +import 'package:app/providers/providers.dart' as _i2; +import 'package:app/values/values.dart' as _i5; +import 'package:audio_service/audio_service.dart' as _i7; +import 'package:audio_session/audio_session.dart' as _i13; +import 'package:just_audio/just_audio.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i12; +import 'package:rxdart/rxdart.dart' as _i4; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeDownloadProvider_0 extends _i1.SmartFake + implements _i2.DownloadProvider { + _FakeDownloadProvider_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePlayableProvider_1 extends _i1.SmartFake + implements _i2.PlayableProvider { + _FakePlayableProvider_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDuration_2 extends _i1.SmartFake implements Duration { + _FakeDuration_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAudioPlayer_3 extends _i1.SmartFake implements _i3.AudioPlayer { + _FakeAudioPlayer_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBehaviorSubject_4 extends _i1.SmartFake + implements _i4.BehaviorSubject { + _FakeBehaviorSubject_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePublishSubject_5 extends _i1.SmartFake + implements _i4.PublishSubject { + _FakePublishSubject_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeValueStream_6 extends _i1.SmartFake + implements _i4.ValueStream { + _FakeValueStream_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePaginationResult_7 extends _i1.SmartFake + implements _i5.PaginationResult { + _FakePaginationResult_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePlaybackEvent_8 extends _i1.SmartFake implements _i3.PlaybackEvent { + _FakePlaybackEvent_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePlayerState_9 extends _i1.SmartFake implements _i3.PlayerState { + _FakePlayerState_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [KoelAudioHandler]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockKoelAudioHandler extends _i1.Mock implements _i6.KoelAudioHandler { + MockKoelAudioHandler() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.DownloadProvider get downloadProvider => (super.noSuchMethod( + Invocation.getter(#downloadProvider), + returnValue: _FakeDownloadProvider_0( + this, + Invocation.getter(#downloadProvider), + ), + ) as _i2.DownloadProvider); + + @override + _i2.PlayableProvider get playableProvider => (super.noSuchMethod( + Invocation.getter(#playableProvider), + returnValue: _FakePlayableProvider_1( + this, + Invocation.getter(#playableProvider), + ), + ) as _i2.PlayableProvider); + + @override + _i7.AudioServiceRepeatMode get repeatMode => (super.noSuchMethod( + Invocation.getter(#repeatMode), + returnValue: _i7.AudioServiceRepeatMode.none, + ) as _i7.AudioServiceRepeatMode); + + @override + Duration get sourceLoadTimeout => (super.noSuchMethod( + Invocation.getter(#sourceLoadTimeout), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#sourceLoadTimeout), + ), + ) as Duration); + + @override + _i3.AudioPlayer get player => (super.noSuchMethod( + Invocation.getter(#player), + returnValue: _FakeAudioPlayer_3( + this, + Invocation.getter(#player), + ), + ) as _i3.AudioPlayer); + + @override + bool get isRadioMode => (super.noSuchMethod( + Invocation.getter(#isRadioMode), + returnValue: false, + ) as bool); + + @override + int get currentQueueIndex => (super.noSuchMethod( + Invocation.getter(#currentQueueIndex), + returnValue: 0, + ) as int); + + @override + set downloadProvider(_i2.DownloadProvider? _downloadProvider) => + super.noSuchMethod( + Invocation.setter( + #downloadProvider, + _downloadProvider, + ), + returnValueForMissingStub: null, + ); + + @override + set playableProvider(_i2.PlayableProvider? _playableProvider) => + super.noSuchMethod( + Invocation.setter( + #playableProvider, + _playableProvider, + ), + returnValueForMissingStub: null, + ); + + @override + set repeatMode(_i7.AudioServiceRepeatMode? _repeatMode) => super.noSuchMethod( + Invocation.setter( + #repeatMode, + _repeatMode, + ), + returnValueForMissingStub: null, + ); + + @override + _i4.BehaviorSubject<_i7.PlaybackState> get playbackState => + (super.noSuchMethod( + Invocation.getter(#playbackState), + returnValue: _FakeBehaviorSubject_4<_i7.PlaybackState>( + this, + Invocation.getter(#playbackState), + ), + ) as _i4.BehaviorSubject<_i7.PlaybackState>); + + @override + _i4.BehaviorSubject> get queue => (super.noSuchMethod( + Invocation.getter(#queue), + returnValue: _FakeBehaviorSubject_4>( + this, + Invocation.getter(#queue), + ), + ) as _i4.BehaviorSubject>); + + @override + _i4.BehaviorSubject get queueTitle => (super.noSuchMethod( + Invocation.getter(#queueTitle), + returnValue: _FakeBehaviorSubject_4( + this, + Invocation.getter(#queueTitle), + ), + ) as _i4.BehaviorSubject); + + @override + _i4.BehaviorSubject<_i7.MediaItem?> get mediaItem => (super.noSuchMethod( + Invocation.getter(#mediaItem), + returnValue: _FakeBehaviorSubject_4<_i7.MediaItem?>( + this, + Invocation.getter(#mediaItem), + ), + ) as _i4.BehaviorSubject<_i7.MediaItem?>); + + @override + _i4.BehaviorSubject<_i7.AndroidPlaybackInfo> get androidPlaybackInfo => + (super.noSuchMethod( + Invocation.getter(#androidPlaybackInfo), + returnValue: _FakeBehaviorSubject_4<_i7.AndroidPlaybackInfo>( + this, + Invocation.getter(#androidPlaybackInfo), + ), + ) as _i4.BehaviorSubject<_i7.AndroidPlaybackInfo>); + + @override + _i4.BehaviorSubject<_i7.RatingStyle> get ratingStyle => (super.noSuchMethod( + Invocation.getter(#ratingStyle), + returnValue: _FakeBehaviorSubject_4<_i7.RatingStyle>( + this, + Invocation.getter(#ratingStyle), + ), + ) as _i4.BehaviorSubject<_i7.RatingStyle>); + + @override + _i4.PublishSubject get customEvent => (super.noSuchMethod( + Invocation.getter(#customEvent), + returnValue: _FakePublishSubject_5( + this, + Invocation.getter(#customEvent), + ), + ) as _i4.PublishSubject); + + @override + _i4.BehaviorSubject get customState => (super.noSuchMethod( + Invocation.getter(#customState), + returnValue: _FakeBehaviorSubject_4( + this, + Invocation.getter(#customState), + ), + ) as _i4.BehaviorSubject); + + @override + dynamic init({ + required _i2.PlayableProvider? playableProvider, + required _i2.DownloadProvider? downloadProvider, + }) => + super.noSuchMethod(Invocation.method( + #init, + [], + { + #playableProvider: playableProvider, + #downloadProvider: downloadProvider, + }, + )); + + @override + void enterRadioMode(_i3.AudioPlayer? radioPlayer) => super.noSuchMethod( + Invocation.method( + #enterRadioMode, + [radioPlayer], + ), + returnValueForMissingStub: null, + ); + + @override + void exitRadioMode() => super.noSuchMethod( + Invocation.method( + #exitRadioMode, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void updateRadioPlaybackState({ + required bool? playing, + required _i7.AudioProcessingState? processingState, + }) => + super.noSuchMethod( + Invocation.method( + #updateRadioPlaybackState, + [], + { + #playing: playing, + #processingState: processingState, + }, + ), + returnValueForMissingStub: null, + ); + + @override + num? getPlaybackPositionFromState(String? playableId) => + (super.noSuchMethod(Invocation.method( + #getPlaybackPositionFromState, + [playableId], + )) as num?); + + @override + void setPlaybackPositionToState( + String? playableId, + num? position, + ) => + super.noSuchMethod( + Invocation.method( + #setPlaybackPositionToState, + [ + playableId, + position, + ], + ), + returnValueForMissingStub: null, + ); + + @override + _i8.Future play() => (super.noSuchMethod( + Invocation.method( + #play, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future stop() => (super.noSuchMethod( + Invocation.method( + #stop, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future queueAndPlay(_i9.Playable? playable) => + (super.noSuchMethod( + Invocation.method( + #queueAndPlay, + [playable], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future maybeQueueAndPlay( + _i9.Playable? playable, { + dynamic position = 0, + }) => + (super.noSuchMethod( + Invocation.method( + #maybeQueueAndPlay, + [playable], + {#position: position}, + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future queueAfterCurrent(_i9.Playable? playable) => + (super.noSuchMethod( + Invocation.method( + #queueAfterCurrent, + [playable], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future playOrPause() => (super.noSuchMethod( + Invocation.method( + #playOrPause, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future skipToNext() => (super.noSuchMethod( + Invocation.method( + #skipToNext, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future seek(Duration? position) => (super.noSuchMethod( + Invocation.method( + #seek, + [position], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future skipToPrevious() => (super.noSuchMethod( + Invocation.method( + #skipToPrevious, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future queued(_i9.Playable? playable) => + (super.noSuchMethod( + Invocation.method( + #queued, + [playable], + ), + returnValue: _i8.Future.value(false), + ) as _i8.Future); + + @override + _i8.Future removeQueueItemAt(int? index) => (super.noSuchMethod( + Invocation.method( + #removeQueueItemAt, + [index], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + void moveQueueItem( + int? oldIndex, + int? newIndex, + ) => + super.noSuchMethod( + Invocation.method( + #moveQueueItem, + [ + oldIndex, + newIndex, + ], + ), + returnValueForMissingStub: null, + ); + + @override + _i8.Future clearQueue() => (super.noSuchMethod( + Invocation.method( + #clearQueue, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setVolume(double? value) => (super.noSuchMethod( + Invocation.method( + #setVolume, + [value], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future replaceQueue( + List<_i9.Playable>? playables, { + bool? shuffle = false, + bool? autoPlay = true, + }) => + (super.noSuchMethod( + Invocation.method( + #replaceQueue, + [playables], + { + #shuffle: shuffle, + #autoPlay: autoPlay, + }, + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future<_i7.AudioServiceRepeatMode> rotateRepeatMode() => + (super.noSuchMethod( + Invocation.method( + #rotateRepeatMode, + [], + ), + returnValue: _i8.Future<_i7.AudioServiceRepeatMode>.value( + _i7.AudioServiceRepeatMode.none), + ) as _i8.Future<_i7.AudioServiceRepeatMode>); + + @override + _i8.Future setRepeatMode(_i7.AudioServiceRepeatMode? repeatMode) => + (super.noSuchMethod( + Invocation.method( + #setRepeatMode, + [repeatMode], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future cleanUpUponLogout() => (super.noSuchMethod( + Invocation.method( + #cleanUpUponLogout, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future queueToBottom(_i9.Playable? playable) => + (super.noSuchMethod( + Invocation.method( + #queueToBottom, + [playable], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future removeFromQueue(_i9.Playable? playable) => + (super.noSuchMethod( + Invocation.method( + #removeFromQueue, + [playable], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future prepare() => (super.noSuchMethod( + Invocation.method( + #prepare, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future prepareFromMediaId( + String? mediaId, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #prepareFromMediaId, + [ + mediaId, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future prepareFromSearch( + String? query, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #prepareFromSearch, + [ + query, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future prepareFromUri( + Uri? uri, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #prepareFromUri, + [ + uri, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future playFromMediaId( + String? mediaId, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #playFromMediaId, + [ + mediaId, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future playFromSearch( + String? query, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #playFromSearch, + [ + query, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future playFromUri( + Uri? uri, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #playFromUri, + [ + uri, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future playMediaItem(_i7.MediaItem? mediaItem) => + (super.noSuchMethod( + Invocation.method( + #playMediaItem, + [mediaItem], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future click([_i7.MediaButton? button = _i7.MediaButton.media]) => + (super.noSuchMethod( + Invocation.method( + #click, + [button], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future addQueueItem(_i7.MediaItem? mediaItem) => + (super.noSuchMethod( + Invocation.method( + #addQueueItem, + [mediaItem], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future addQueueItems(List<_i7.MediaItem>? mediaItems) => + (super.noSuchMethod( + Invocation.method( + #addQueueItems, + [mediaItems], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future insertQueueItem( + int? index, + _i7.MediaItem? mediaItem, + ) => + (super.noSuchMethod( + Invocation.method( + #insertQueueItem, + [ + index, + mediaItem, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future updateQueue(List<_i7.MediaItem>? queue) => + (super.noSuchMethod( + Invocation.method( + #updateQueue, + [queue], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future updateMediaItem(_i7.MediaItem? mediaItem) => + (super.noSuchMethod( + Invocation.method( + #updateMediaItem, + [mediaItem], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future removeQueueItem(_i7.MediaItem? mediaItem) => + (super.noSuchMethod( + Invocation.method( + #removeQueueItem, + [mediaItem], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future fastForward() => (super.noSuchMethod( + Invocation.method( + #fastForward, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future rewind() => (super.noSuchMethod( + Invocation.method( + #rewind, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future skipToQueueItem(int? index) => (super.noSuchMethod( + Invocation.method( + #skipToQueueItem, + [index], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setRating( + _i7.Rating? rating, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #setRating, + [ + rating, + extras, + ], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setCaptioningEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setCaptioningEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setShuffleMode(_i7.AudioServiceShuffleMode? shuffleMode) => + (super.noSuchMethod( + Invocation.method( + #setShuffleMode, + [shuffleMode], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future seekBackward(bool? begin) => (super.noSuchMethod( + Invocation.method( + #seekBackward, + [begin], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future seekForward(bool? begin) => (super.noSuchMethod( + Invocation.method( + #seekForward, + [begin], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setSpeed(double? speed) => (super.noSuchMethod( + Invocation.method( + #setSpeed, + [speed], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future customAction( + String? name, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #customAction, + [ + name, + extras, + ], + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future onTaskRemoved() => (super.noSuchMethod( + Invocation.method( + #onTaskRemoved, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future onNotificationDeleted() => (super.noSuchMethod( + Invocation.method( + #onNotificationDeleted, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future> getChildren( + String? parentMediaId, [ + Map? options, + ]) => + (super.noSuchMethod( + Invocation.method( + #getChildren, + [ + parentMediaId, + options, + ], + ), + returnValue: _i8.Future>.value(<_i7.MediaItem>[]), + ) as _i8.Future>); + + @override + _i4.ValueStream> subscribeToChildren( + String? parentMediaId) => + (super.noSuchMethod( + Invocation.method( + #subscribeToChildren, + [parentMediaId], + ), + returnValue: _FakeValueStream_6>( + this, + Invocation.method( + #subscribeToChildren, + [parentMediaId], + ), + ), + ) as _i4.ValueStream>); + + @override + _i8.Future<_i7.MediaItem?> getMediaItem(String? mediaId) => + (super.noSuchMethod( + Invocation.method( + #getMediaItem, + [mediaId], + ), + returnValue: _i8.Future<_i7.MediaItem?>.value(), + ) as _i8.Future<_i7.MediaItem?>); + + @override + _i8.Future> search( + String? query, [ + Map? extras, + ]) => + (super.noSuchMethod( + Invocation.method( + #search, + [ + query, + extras, + ], + ), + returnValue: _i8.Future>.value(<_i7.MediaItem>[]), + ) as _i8.Future>); + + @override + _i8.Future androidAdjustRemoteVolume( + _i7.AndroidVolumeDirection? direction) => + (super.noSuchMethod( + Invocation.method( + #androidAdjustRemoteVolume, + [direction], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future androidSetRemoteVolume(int? volumeIndex) => + (super.noSuchMethod( + Invocation.method( + #androidSetRemoteVolume, + [volumeIndex], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); +} + +/// A class which mocks [PlayableProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPlayableProvider extends _i1.Mock implements _i2.PlayableProvider { + MockPlayableProvider() { + _i1.throwOnMissingStub(this); + } + + @override + List<_i9.Playable> get playables => (super.noSuchMethod( + Invocation.getter(#playables), + returnValue: <_i9.Playable>[], + ) as List<_i9.Playable>); + + @override + set playables(List<_i9.Playable>? _playables) => super.noSuchMethod( + Invocation.setter( + #playables, + _playables, + ), + returnValueForMissingStub: null, + ); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + ) as bool); + + @override + List<_i9.Playable> syncWithVault(dynamic _playables) => + (super.noSuchMethod( + Invocation.method( + #syncWithVault, + [_playables], + ), + returnValue: <_i9.Playable>[], + ) as List<_i9.Playable>); + + @override + _i9.Playable? byId(String? id) => + (super.noSuchMethod(Invocation.method( + #byId, + [id], + )) as _i9.Playable?); + + @override + _i8.Future<_i5.PaginationResult<_i9.Playable>> paginate( + _i2.PlayablePaginationConfig? config) => + (super.noSuchMethod( + Invocation.method( + #paginate, + [config], + ), + returnValue: + _i8.Future<_i5.PaginationResult<_i9.Playable>>.value( + _FakePaginationResult_7<_i9.Playable>( + this, + Invocation.method( + #paginate, + [config], + ), + )), + ) as _i8.Future<_i5.PaginationResult<_i9.Playable>>); + + @override + _i8.Future>> fetchForArtist( + dynamic artistId, { + bool? forceRefresh = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForArtist, + [artistId], + {#forceRefresh: forceRefresh}, + ), + returnValue: _i8.Future>>.value( + <_i9.Playable>[]), + ) as _i8.Future>>); + + @override + _i8.Future<_i5.PaginationResult<_i9.Playable>> paginateByGenre( + String? genreId, { + int? page = 1, + String? sort = 'title', + _i10.SortOrder? order = _i10.SortOrder.asc, + }) => + (super.noSuchMethod( + Invocation.method( + #paginateByGenre, + [genreId], + { + #page: page, + #sort: sort, + #order: order, + }, + ), + returnValue: + _i8.Future<_i5.PaginationResult<_i9.Playable>>.value( + _FakePaginationResult_7<_i9.Playable>( + this, + Invocation.method( + #paginateByGenre, + [genreId], + { + #page: page, + #sort: sort, + #order: order, + }, + ), + )), + ) as _i8.Future<_i5.PaginationResult<_i9.Playable>>); + + @override + _i8.Future>> fetchForAlbum( + dynamic albumId, { + bool? forceRefresh = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForAlbum, + [albumId], + {#forceRefresh: forceRefresh}, + ), + returnValue: _i8.Future>>.value( + <_i9.Playable>[]), + ) as _i8.Future>>); + + @override + _i8.Future>> fetchForPlaylist( + dynamic playlistId, { + bool? forceRefresh = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForPlaylist, + [playlistId], + {#forceRefresh: forceRefresh}, + ), + returnValue: _i8.Future>>.value( + <_i9.Playable>[]), + ) as _i8.Future>>); + + @override + _i8.Future>> fetchForPodcast( + String? podcastId, { + bool? forceRefresh = false, + bool? getUpdates = false, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchForPodcast, + [podcastId], + { + #forceRefresh: forceRefresh, + #getUpdates: getUpdates, + }, + ), + returnValue: _i8.Future>>.value( + <_i9.Playable>[]), + ) as _i8.Future>>); + + @override + _i8.Future>> fetchRandom({int? limit = 500}) => + (super.noSuchMethod( + Invocation.method( + #fetchRandom, + [], + {#limit: limit}, + ), + returnValue: _i8.Future>>.value( + <_i9.Playable>[]), + ) as _i8.Future>>); + + @override + _i8.Future>> fetchInOrder({ + String? sortField = 'title', + _i10.SortOrder? order = _i10.SortOrder.asc, + int? limit = 500, + }) => + (super.noSuchMethod( + Invocation.method( + #fetchInOrder, + [], + { + #sortField: sortField, + #order: order, + #limit: limit, + }, + ), + returnValue: _i8.Future>>.value( + <_i9.Playable>[]), + ) as _i8.Future>>); + + @override + List<_i9.Playable> parseFromJson(dynamic json) => + (super.noSuchMethod( + Invocation.method( + #parseFromJson, + [json], + ), + returnValue: <_i9.Playable>[], + ) as List<_i9.Playable>); + + @override + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void unsubscribeAll() => super.noSuchMethod( + Invocation.method( + #unsubscribeAll, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void subscribe(_i8.StreamSubscription? sub) => super.noSuchMethod( + Invocation.method( + #subscribe, + [sub], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [RadioPlayerProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockRadioPlayerProvider extends _i1.Mock + implements _i2.RadioPlayerProvider { + MockRadioPlayerProvider() { + _i1.throwOnMissingStub(this); + } + + @override + bool get playing => (super.noSuchMethod( + Invocation.getter(#playing), + returnValue: false, + ) as bool); + + @override + bool get loading => (super.noSuchMethod( + Invocation.getter(#loading), + returnValue: false, + ) as bool); + + @override + bool get active => (super.noSuchMethod( + Invocation.getter(#active), + returnValue: false, + ) as bool); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + ) as bool); + + @override + _i8.Future play(_i9.RadioStation? station) => (super.noSuchMethod( + Invocation.method( + #play, + [station], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future stop() => (super.noSuchMethod( + Invocation.method( + #stop, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future togglePlayPause() => (super.noSuchMethod( + Invocation.method( + #togglePlayPause, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + void refreshMediaItem() => super.noSuchMethod( + Invocation.method( + #refreshMediaItem, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [AudioPlayer]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAudioPlayer extends _i1.Mock implements _i3.AudioPlayer { + MockAudioPlayer() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.PlaybackEvent get playbackEvent => (super.noSuchMethod( + Invocation.getter(#playbackEvent), + returnValue: _FakePlaybackEvent_8( + this, + Invocation.getter(#playbackEvent), + ), + ) as _i3.PlaybackEvent); + + @override + _i8.Stream<_i3.PlaybackEvent> get playbackEventStream => (super.noSuchMethod( + Invocation.getter(#playbackEventStream), + returnValue: _i8.Stream<_i3.PlaybackEvent>.empty(), + ) as _i8.Stream<_i3.PlaybackEvent>); + + @override + _i8.Stream get durationStream => (super.noSuchMethod( + Invocation.getter(#durationStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i3.ProcessingState get processingState => (super.noSuchMethod( + Invocation.getter(#processingState), + returnValue: _i3.ProcessingState.idle, + ) as _i3.ProcessingState); + + @override + _i8.Stream<_i3.ProcessingState> get processingStateStream => + (super.noSuchMethod( + Invocation.getter(#processingStateStream), + returnValue: _i8.Stream<_i3.ProcessingState>.empty(), + ) as _i8.Stream<_i3.ProcessingState>); + + @override + bool get playing => (super.noSuchMethod( + Invocation.getter(#playing), + returnValue: false, + ) as bool); + + @override + _i8.Stream get playingStream => (super.noSuchMethod( + Invocation.getter(#playingStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + double get volume => (super.noSuchMethod( + Invocation.getter(#volume), + returnValue: 0.0, + ) as double); + + @override + _i8.Stream get volumeStream => (super.noSuchMethod( + Invocation.getter(#volumeStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + double get speed => (super.noSuchMethod( + Invocation.getter(#speed), + returnValue: 0.0, + ) as double); + + @override + _i8.Stream get speedStream => (super.noSuchMethod( + Invocation.getter(#speedStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + double get pitch => (super.noSuchMethod( + Invocation.getter(#pitch), + returnValue: 0.0, + ) as double); + + @override + _i8.Stream get pitchStream => (super.noSuchMethod( + Invocation.getter(#pitchStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + bool get skipSilenceEnabled => (super.noSuchMethod( + Invocation.getter(#skipSilenceEnabled), + returnValue: false, + ) as bool); + + @override + _i8.Stream get skipSilenceEnabledStream => (super.noSuchMethod( + Invocation.getter(#skipSilenceEnabledStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + Duration get bufferedPosition => (super.noSuchMethod( + Invocation.getter(#bufferedPosition), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#bufferedPosition), + ), + ) as Duration); + + @override + _i8.Stream get bufferedPositionStream => (super.noSuchMethod( + Invocation.getter(#bufferedPositionStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i8.Stream<_i3.IcyMetadata?> get icyMetadataStream => (super.noSuchMethod( + Invocation.getter(#icyMetadataStream), + returnValue: _i8.Stream<_i3.IcyMetadata?>.empty(), + ) as _i8.Stream<_i3.IcyMetadata?>); + + @override + _i3.PlayerState get playerState => (super.noSuchMethod( + Invocation.getter(#playerState), + returnValue: _FakePlayerState_9( + this, + Invocation.getter(#playerState), + ), + ) as _i3.PlayerState); + + @override + _i8.Stream<_i3.PlayerState> get playerStateStream => (super.noSuchMethod( + Invocation.getter(#playerStateStream), + returnValue: _i8.Stream<_i3.PlayerState>.empty(), + ) as _i8.Stream<_i3.PlayerState>); + + @override + _i8.Stream?> get sequenceStream => + (super.noSuchMethod( + Invocation.getter(#sequenceStream), + returnValue: _i8.Stream?>.empty(), + ) as _i8.Stream?>); + + @override + _i8.Stream?> get shuffleIndicesStream => (super.noSuchMethod( + Invocation.getter(#shuffleIndicesStream), + returnValue: _i8.Stream?>.empty(), + ) as _i8.Stream?>); + + @override + _i8.Stream get currentIndexStream => (super.noSuchMethod( + Invocation.getter(#currentIndexStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i8.Stream<_i3.SequenceState?> get sequenceStateStream => (super.noSuchMethod( + Invocation.getter(#sequenceStateStream), + returnValue: _i8.Stream<_i3.SequenceState?>.empty(), + ) as _i8.Stream<_i3.SequenceState?>); + + @override + bool get hasNext => (super.noSuchMethod( + Invocation.getter(#hasNext), + returnValue: false, + ) as bool); + + @override + bool get hasPrevious => (super.noSuchMethod( + Invocation.getter(#hasPrevious), + returnValue: false, + ) as bool); + + @override + _i3.LoopMode get loopMode => (super.noSuchMethod( + Invocation.getter(#loopMode), + returnValue: _i3.LoopMode.off, + ) as _i3.LoopMode); + + @override + _i8.Stream<_i3.LoopMode> get loopModeStream => (super.noSuchMethod( + Invocation.getter(#loopModeStream), + returnValue: _i8.Stream<_i3.LoopMode>.empty(), + ) as _i8.Stream<_i3.LoopMode>); + + @override + bool get shuffleModeEnabled => (super.noSuchMethod( + Invocation.getter(#shuffleModeEnabled), + returnValue: false, + ) as bool); + + @override + _i8.Stream get shuffleModeEnabledStream => (super.noSuchMethod( + Invocation.getter(#shuffleModeEnabledStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i8.Stream get androidAudioSessionIdStream => (super.noSuchMethod( + Invocation.getter(#androidAudioSessionIdStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i8.Stream<_i3.PositionDiscontinuity> get positionDiscontinuityStream => + (super.noSuchMethod( + Invocation.getter(#positionDiscontinuityStream), + returnValue: _i8.Stream<_i3.PositionDiscontinuity>.empty(), + ) as _i8.Stream<_i3.PositionDiscontinuity>); + + @override + bool get automaticallyWaitsToMinimizeStalling => (super.noSuchMethod( + Invocation.getter(#automaticallyWaitsToMinimizeStalling), + returnValue: false, + ) as bool); + + @override + bool get canUseNetworkResourcesForLiveStreamingWhilePaused => + (super.noSuchMethod( + Invocation.getter(#canUseNetworkResourcesForLiveStreamingWhilePaused), + returnValue: false, + ) as bool); + + @override + double get preferredPeakBitRate => (super.noSuchMethod( + Invocation.getter(#preferredPeakBitRate), + returnValue: 0.0, + ) as double); + + @override + bool get allowsExternalPlayback => (super.noSuchMethod( + Invocation.getter(#allowsExternalPlayback), + returnValue: false, + ) as bool); + + @override + String get webSinkId => (super.noSuchMethod( + Invocation.getter(#webSinkId), + returnValue: _i12.dummyValue( + this, + Invocation.getter(#webSinkId), + ), + ) as String); + + @override + Duration get position => (super.noSuchMethod( + Invocation.getter(#position), + returnValue: _FakeDuration_2( + this, + Invocation.getter(#position), + ), + ) as Duration); + + @override + _i8.Stream get positionStream => (super.noSuchMethod( + Invocation.getter(#positionStream), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i8.Stream createPositionStream({ + int? steps = 800, + Duration? minPeriod = const Duration(milliseconds: 200), + Duration? maxPeriod = const Duration(milliseconds: 200), + }) => + (super.noSuchMethod( + Invocation.method( + #createPositionStream, + [], + { + #steps: steps, + #minPeriod: minPeriod, + #maxPeriod: maxPeriod, + }, + ), + returnValue: _i8.Stream.empty(), + ) as _i8.Stream); + + @override + _i8.Future setUrl( + String? url, { + Map? headers, + Duration? initialPosition, + bool? preload = true, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setUrl, + [url], + { + #headers: headers, + #initialPosition: initialPosition, + #preload: preload, + #tag: tag, + }, + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setFilePath( + String? filePath, { + Duration? initialPosition, + bool? preload = true, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setFilePath, + [filePath], + { + #initialPosition: initialPosition, + #preload: preload, + #tag: tag, + }, + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setAsset( + String? assetPath, { + String? package, + bool? preload = true, + Duration? initialPosition, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setAsset, + [assetPath], + { + #package: package, + #preload: preload, + #initialPosition: initialPosition, + #tag: tag, + }, + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setAudioSource( + _i3.AudioSource? source, { + bool? preload = true, + int? initialIndex, + Duration? initialPosition, + }) => + (super.noSuchMethod( + Invocation.method( + #setAudioSource, + [source], + { + #preload: preload, + #initialIndex: initialIndex, + #initialPosition: initialPosition, + }, + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future load() => (super.noSuchMethod( + Invocation.method( + #load, + [], + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setClip({ + Duration? start, + Duration? end, + dynamic tag, + }) => + (super.noSuchMethod( + Invocation.method( + #setClip, + [], + { + #start: start, + #end: end, + #tag: tag, + }, + ), + returnValue: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future play() => (super.noSuchMethod( + Invocation.method( + #play, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future pause() => (super.noSuchMethod( + Invocation.method( + #pause, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future stop() => (super.noSuchMethod( + Invocation.method( + #stop, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setVolume(double? volume) => (super.noSuchMethod( + Invocation.method( + #setVolume, + [volume], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setSkipSilenceEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setSkipSilenceEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setSpeed(double? speed) => (super.noSuchMethod( + Invocation.method( + #setSpeed, + [speed], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setPitch(double? pitch) => (super.noSuchMethod( + Invocation.method( + #setPitch, + [pitch], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setLoopMode(_i3.LoopMode? mode) => (super.noSuchMethod( + Invocation.method( + #setLoopMode, + [mode], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setShuffleModeEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setShuffleModeEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future shuffle() => (super.noSuchMethod( + Invocation.method( + #shuffle, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setAutomaticallyWaitsToMinimizeStalling( + bool? automaticallyWaitsToMinimizeStalling) => + (super.noSuchMethod( + Invocation.method( + #setAutomaticallyWaitsToMinimizeStalling, + [automaticallyWaitsToMinimizeStalling], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setCanUseNetworkResourcesForLiveStreamingWhilePaused( + bool? canUseNetworkResourcesForLiveStreamingWhilePaused) => + (super.noSuchMethod( + Invocation.method( + #setCanUseNetworkResourcesForLiveStreamingWhilePaused, + [canUseNetworkResourcesForLiveStreamingWhilePaused], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setPreferredPeakBitRate(double? preferredPeakBitRate) => + (super.noSuchMethod( + Invocation.method( + #setPreferredPeakBitRate, + [preferredPeakBitRate], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setAllowsExternalPlayback(bool? allowsExternalPlayback) => + (super.noSuchMethod( + Invocation.method( + #setAllowsExternalPlayback, + [allowsExternalPlayback], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future seek( + Duration? position, { + int? index, + }) => + (super.noSuchMethod( + Invocation.method( + #seek, + [position], + {#index: index}, + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future seekToNext() => (super.noSuchMethod( + Invocation.method( + #seekToNext, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future seekToPrevious() => (super.noSuchMethod( + Invocation.method( + #seekToPrevious, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setAndroidAudioAttributes( + _i13.AndroidAudioAttributes? audioAttributes) => + (super.noSuchMethod( + Invocation.method( + #setAndroidAudioAttributes, + [audioAttributes], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setWebCrossOrigin(_i3.WebCrossOrigin? webCrossOrigin) => + (super.noSuchMethod( + Invocation.method( + #setWebCrossOrigin, + [webCrossOrigin], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setWebSinkId(String? webSinkId) => (super.noSuchMethod( + Invocation.method( + #setWebSinkId, + [webSinkId], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); +}