Files
ReelShort/test/player/player_render_stack_test.dart
T

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;
}