mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-22 07:18:38 +02:00
162 lines
5.5 KiB
Dart
162 lines
5.5 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
|
import 'package:spotiflac_android/theme/mornye_theme.dart';
|
|
import 'package:spotiflac_android/widgets/app_slider.dart';
|
|
import 'package:spotiflac_android/widgets/player_volume_control.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
test('In-app volume writes suppress the system volume panel', () async {
|
|
const channel = MethodChannel('com.kurenai7968.volume_controller.method');
|
|
final calls = <MethodCall>[];
|
|
final messenger =
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
|
|
messenger.setMockMethodCallHandler(
|
|
channel,
|
|
(call) async => calls.add(call),
|
|
);
|
|
addTearDown(() => messenger.setMockMethodCallHandler(channel, null));
|
|
final container = ProviderContainer();
|
|
addTearDown(container.dispose);
|
|
await container.read(systemVolumeWriterProvider)(0.7);
|
|
expect(calls.single.method, 'setVolume');
|
|
expect(calls.single.arguments, {'volume': 0.7, 'showSystemUI': false});
|
|
});
|
|
|
|
testWidgets('Slow volume writes coalesce and cannot reset an active drag', (
|
|
tester,
|
|
) async {
|
|
final writes = <double>[];
|
|
final completions = <Completer<void>>[];
|
|
final volumes = StreamController<double>();
|
|
addTearDown(volumes.close);
|
|
await tester.pumpWidget(
|
|
ProviderScope(
|
|
overrides: [
|
|
systemVolumeProvider.overrideWith((ref) => volumes.stream),
|
|
systemVolumeWriterProvider.overrideWith(
|
|
(ref) => (value) {
|
|
writes.add(value);
|
|
final completion = Completer<void>();
|
|
completions.add(completion);
|
|
return completion.future;
|
|
},
|
|
),
|
|
],
|
|
child: MaterialApp(
|
|
// The Mornye glass slider, which reports drag start itself.
|
|
theme: MornyeTheme.build(Brightness.dark),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: const Scaffold(body: PlayerVolumeControl()),
|
|
),
|
|
),
|
|
);
|
|
volumes.add(0.5);
|
|
await tester.pumpAndSettle();
|
|
Slider slider() => tester.widget(find.byType(Slider));
|
|
|
|
slider().onChangeStart!(0.5);
|
|
slider().onChanged!(0.6);
|
|
slider().onChanged!(0.7);
|
|
slider().onChanged!(0.8);
|
|
await tester.pump();
|
|
expect(writes, [0.6]);
|
|
expect(slider().value, 0.8);
|
|
|
|
completions.first.complete();
|
|
await tester.pump();
|
|
expect(writes, [0.6, 0.8]);
|
|
volumes.add(0.6);
|
|
completions.last.complete();
|
|
await tester.pump();
|
|
expect(slider().value, 0.8);
|
|
|
|
slider().onChangeEnd!(0.8);
|
|
slider().onChangeStart!(0.8);
|
|
slider().onChanged!(0.9);
|
|
completions.last.complete();
|
|
await tester.pump();
|
|
expect(writes.last, 0.9);
|
|
completions.last.complete();
|
|
await tester.pump();
|
|
expect(slider().value, 0.9);
|
|
|
|
slider().onChangeEnd!(0.9);
|
|
volumes.add(0.9);
|
|
completions.last.complete();
|
|
await tester.pump();
|
|
volumes.add(0.3);
|
|
await tester.pumpAndSettle();
|
|
expect(slider().value, 0.3);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
for (final reducedMotion in [false, true]) {
|
|
testWidgets(
|
|
'Material holds dragged volume (reduced motion: $reducedMotion)',
|
|
(tester) async {
|
|
final writes = <double>[];
|
|
final volumes = StreamController<double>();
|
|
addTearDown(volumes.close);
|
|
await tester.pumpWidget(
|
|
ProviderScope(
|
|
overrides: [
|
|
systemVolumeProvider.overrideWith((ref) => volumes.stream),
|
|
systemVolumeWriterProvider.overrideWith(
|
|
(ref) =>
|
|
(value) async => writes.add(value),
|
|
),
|
|
],
|
|
child: MaterialApp(
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: MediaQuery(
|
|
data: MediaQueryData(disableAnimations: reducedMotion),
|
|
child: const Scaffold(body: PlayerVolumeControl()),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
volumes.add(0.5);
|
|
await tester.pumpAndSettle();
|
|
AppSlider slider() => tester.widget(find.byType(AppSlider));
|
|
expect(slider().value, 0.5);
|
|
|
|
// A finger on the track: the write finishes and the system echoes an
|
|
// older level, but the thumb stays where the user put it.
|
|
final finger = await tester.startGesture(
|
|
tester.getCenter(find.byType(AppSlider)),
|
|
);
|
|
await finger.moveBy(const Offset(20, 0));
|
|
await tester.pump();
|
|
await finger.moveBy(const Offset(100, 0));
|
|
await tester.pump();
|
|
final draggedVolume = slider().value;
|
|
expect(draggedVolume, greaterThan(0.5));
|
|
expect(writes.last, draggedVolume);
|
|
volumes.add(0.6);
|
|
await tester.pump();
|
|
expect(slider().value, draggedVolume);
|
|
|
|
// Once the finger lifts the slider follows the system again.
|
|
await finger.up();
|
|
expect(writes.last, draggedVolume);
|
|
volumes.add(draggedVolume);
|
|
await tester.pumpAndSettle();
|
|
expect(slider().value, draggedVolume);
|
|
volumes.add(0.2);
|
|
await tester.pumpAndSettle();
|
|
expect(slider().value, 0.2);
|
|
expect(tester.takeException(), isNull);
|
|
},
|
|
);
|
|
}
|
|
}
|