149 lines
4.8 KiB
Dart
149 lines
4.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:fruitshorts/pages/player/widgets/player_render_stack.dart';
|
|
import 'package:fruitshorts/pages/player/widgets/player_video_surface.dart';
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
void main() {
|
|
testWidgets('should_keep_slots_alive_and_only_translate_during_page_change', (
|
|
tester,
|
|
) async {
|
|
final pages = PageController(initialPage: 1);
|
|
final previousController = _controller('previous');
|
|
final currentController = _controller('current');
|
|
final nextController = _controller('next');
|
|
addTearDown(pages.dispose);
|
|
addTearDown(previousController.dispose);
|
|
addTearDown(currentController.dispose);
|
|
addTearDown(nextController.dispose);
|
|
|
|
var currentIndex = 1;
|
|
late StateSetter rebuild;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: StatefulBuilder(
|
|
builder: (context, setState) {
|
|
rebuild = setState;
|
|
return Stack(
|
|
fit: StackFit.expand,
|
|
children: [
|
|
PlayerRenderStack(
|
|
pageController: pages,
|
|
slots: _slots(
|
|
currentIndex: currentIndex,
|
|
previousController: previousController,
|
|
currentController: currentController,
|
|
nextController: nextController,
|
|
),
|
|
),
|
|
PageView(
|
|
controller: pages,
|
|
children: const [
|
|
SizedBox.expand(key: Key('page-0')),
|
|
SizedBox.expand(key: Key('page-1')),
|
|
SizedBox.expand(key: Key('page-2')),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
|
|
final currentSlot = find.byKey(
|
|
const ValueKey('player-render-slot-current'),
|
|
);
|
|
final currentState = tester.state(currentSlot);
|
|
final currentElement = tester.element(currentSlot);
|
|
final currentSurface = tester.widget<PlayerVideoSurface>(currentSlot);
|
|
expect(currentSurface.controller, same(currentController));
|
|
expect(_translationY(tester, 'current'), 0);
|
|
expect(_translationY(tester, 'next'), greaterThan(0));
|
|
|
|
pages.jumpToPage(2);
|
|
await tester.pump();
|
|
await tester.pump();
|
|
|
|
expect(tester.state(currentSlot), same(currentState));
|
|
expect(tester.element(currentSlot), same(currentElement));
|
|
expect(
|
|
tester.widget<PlayerVideoSurface>(currentSlot).controller,
|
|
same(currentController),
|
|
);
|
|
expect(_translationY(tester, 'current'), lessThan(0));
|
|
expect(_translationY(tester, 'next'), 0);
|
|
|
|
rebuild(() => currentIndex = 2);
|
|
await tester.pump();
|
|
|
|
expect(tester.state(currentSlot), same(currentState));
|
|
expect(tester.element(currentSlot), same(currentElement));
|
|
expect(_translationY(tester, 'current'), 0);
|
|
expect(_translationY(tester, 'previous'), lessThan(0));
|
|
expect(
|
|
find.descendant(
|
|
of: find.byType(PlayerRenderStack),
|
|
matching: find.byType(IgnorePointer),
|
|
),
|
|
findsOneWidget,
|
|
);
|
|
});
|
|
}
|
|
|
|
Map<PlayerRenderSlotRole, PlayerRenderSlotData> _slots({
|
|
required int currentIndex,
|
|
required VideoPlayerController previousController,
|
|
required VideoPlayerController currentController,
|
|
required VideoPlayerController nextController,
|
|
}) {
|
|
return {
|
|
PlayerRenderSlotRole.previous: PlayerRenderSlotData(
|
|
role: PlayerRenderSlotRole.previous,
|
|
index: currentIndex - 1,
|
|
pagePosition: (currentIndex - 1).toDouble(),
|
|
controller: previousController,
|
|
placeholder: const ColoredBox(
|
|
key: Key('previous-placeholder'),
|
|
color: Colors.red,
|
|
),
|
|
),
|
|
PlayerRenderSlotRole.current: PlayerRenderSlotData(
|
|
role: PlayerRenderSlotRole.current,
|
|
index: currentIndex,
|
|
pagePosition: currentIndex.toDouble(),
|
|
controller: currentController,
|
|
placeholder: const ColoredBox(
|
|
key: Key('current-placeholder'),
|
|
color: Colors.green,
|
|
),
|
|
),
|
|
PlayerRenderSlotRole.next: PlayerRenderSlotData(
|
|
role: PlayerRenderSlotRole.next,
|
|
index: currentIndex + 1,
|
|
pagePosition: (currentIndex + 1).toDouble(),
|
|
controller: nextController,
|
|
placeholder: const ColoredBox(
|
|
key: Key('next-placeholder'),
|
|
color: Colors.blue,
|
|
),
|
|
),
|
|
};
|
|
}
|
|
|
|
VideoPlayerController _controller(String name) {
|
|
return VideoPlayerController.networkUrl(
|
|
Uri.parse('https://example.test/$name.mp4'),
|
|
);
|
|
}
|
|
|
|
double _translationY(WidgetTester tester, String role) {
|
|
final transform = tester.widget<Transform>(
|
|
find.byKey(Key('player-render-transform-$role')),
|
|
);
|
|
return transform.transform.getTranslation().y;
|
|
}
|