mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-22 07:18:38 +02:00
164 lines
5.4 KiB
Dart
164 lines
5.4 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:audio_service/audio_service.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:spotiflac_android/controllers/player_metadata_controller.dart';
|
|
import 'package:spotiflac_android/l10n/app_localizations.dart';
|
|
import 'package:spotiflac_android/services/audio_route_info.dart';
|
|
import 'package:spotiflac_android/widgets/audio_info_sheet.dart';
|
|
|
|
const _route = MethodChannel('com.zarz.spotiflac/audio_route');
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
tearDown(() {
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
.setMockMethodCallHandler(_route, null);
|
|
});
|
|
|
|
test('route info tolerates partial platform maps', () {
|
|
final info = AudioRouteInfo.fromMap({
|
|
'mixerSampleRate': 48000,
|
|
'framesPerBuffer': 192,
|
|
'device': {
|
|
'type': 'usb',
|
|
'sampleRates': [48000, 44100, 0],
|
|
'mixer': {'sampleRate': 96000, 'bitPerfect': true},
|
|
},
|
|
'spatializer': {'available': false},
|
|
});
|
|
|
|
expect(info.bufferMs, 4);
|
|
expect(info.device?.sampleRates, [48000, 44100]);
|
|
expect(info.device?.mixerSampleRate, 96000);
|
|
expect(info.device?.mixerBitPerfect, isTrue);
|
|
expect(info.spatialAvailable, isFalse);
|
|
expect(info.stream, isNull);
|
|
});
|
|
|
|
testWidgets('shows source, signal and resampling to the output device', (
|
|
tester,
|
|
) async {
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
.setMockMethodCallHandler(
|
|
_route,
|
|
(call) async => {
|
|
'platform': 'android',
|
|
'mixerSampleRate': 48000,
|
|
'framesPerBuffer': 96,
|
|
'device': {
|
|
'type': 'usb',
|
|
'name': 'Example DAC',
|
|
// A leftover preference must not claim bit-perfect playback.
|
|
'mixer': {'sampleRate': 48000, 'bitPerfect': true},
|
|
},
|
|
},
|
|
);
|
|
final metadata = PlayerMetadataController();
|
|
addTearDown(metadata.dispose);
|
|
await metadata.load(
|
|
const MediaItem(
|
|
id: 'track',
|
|
title: 'Track',
|
|
extras: {
|
|
'source': 'https://example.com/track.flac',
|
|
'format': 'flac',
|
|
'bit_depth': 24,
|
|
'sample_rate': 96000,
|
|
},
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Builder(
|
|
builder: (context) => TextButton(
|
|
onPressed: () => showAudioInfoSheet(context, metadata: metadata),
|
|
child: const Text('open'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.text('open'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Audio info'), findsOneWidget);
|
|
expect(find.text('Hi-Res Lossless'), findsOneWidget);
|
|
expect(find.text('96 kHz'), findsOneWidget);
|
|
expect(find.text('Up to 48 kHz (Nyquist)'), findsOneWidget);
|
|
expect(find.text('144 dB'), findsOneWidget);
|
|
expect(find.text('No ReplayGain tags'), findsOneWidget);
|
|
await tester.scrollUntilVisible(find.text('96 kHz → 48 kHz'), 200);
|
|
expect(find.text('96 kHz → 48 kHz'), findsOneWidget);
|
|
expect(find.text('Yes, unaltered samples'), findsNothing);
|
|
await tester.scrollUntilVisible(find.text('USB audio · Example DAC'), 200);
|
|
await tester.scrollUntilVisible(find.text('2.0 ms · 96 frames'), 200);
|
|
expect(find.text('2.0 ms · 96 frames'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('late route replies cannot replace the latest track snapshot', (
|
|
tester,
|
|
) async {
|
|
final replies = <Completer<Map<String, dynamic>>>[];
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
.setMockMethodCallHandler(_route, (call) {
|
|
final reply = Completer<Map<String, dynamic>>();
|
|
replies.add(reply);
|
|
return reply.future;
|
|
});
|
|
final metadata = PlayerMetadataController();
|
|
addTearDown(metadata.dispose);
|
|
Future<void> load(String id) => metadata.load(
|
|
MediaItem(
|
|
id: id,
|
|
title: id,
|
|
extras: {
|
|
'source': 'https://example.test/$id.flac',
|
|
'format': 'flac',
|
|
'bit_depth': 24,
|
|
'sample_rate': 96000,
|
|
},
|
|
),
|
|
);
|
|
await load('a');
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Builder(
|
|
builder: (context) => TextButton(
|
|
onPressed: () => showAudioInfoSheet(context, metadata: metadata),
|
|
child: const Text('open'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.text('open'));
|
|
await tester.pumpAndSettle();
|
|
await load('b');
|
|
await tester.pump();
|
|
await load('a');
|
|
await tester.pump();
|
|
expect(replies, hasLength(3));
|
|
replies.last.complete({
|
|
'mixerSampleRate': 96000,
|
|
'device': {'type': 'usb', 'name': 'Current DAC'},
|
|
});
|
|
await tester.pumpAndSettle();
|
|
for (final reply in replies.take(2)) {
|
|
reply.complete({
|
|
'mixerSampleRate': 48000,
|
|
'device': {'type': 'usb', 'name': 'Stale DAC'},
|
|
});
|
|
}
|
|
await tester.pumpAndSettle();
|
|
await tester.scrollUntilVisible(find.text('USB audio · Current DAC'), 200);
|
|
expect(find.text('USB audio · Stale DAC'), findsNothing);
|
|
});
|
|
}
|