fix(player): 使用雪碧图预热首帧兜底
This commit is contained in:
1 parent
48b4e67d34
commit
70d8e0f982
13 files changed
+207
-322
No files matched your search
@@ -5,8 +5,9 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/core/data/services/sprite_thumbnail_asset_loader.dart';
|
||||
import 'package:fruitshorts/core/widgets/remote_image.dart';
|
||||
import 'package:fruitshorts/core/data/services/sprite_thumbnail_axis.dart';
|
||||
import 'package:fruitshorts/pages/player/widgets/player_opening_frame.dart';
|
||||
import 'package:fruitshorts/pages/player/widgets/scrub_preview_card.dart';
|
||||
|
||||
const String _spriteVtt = '''
|
||||
WEBVTT
|
||||
@@ -16,49 +17,46 @@ sprite_001.jpg#xywh=0,0,160,90
|
||||
''';
|
||||
|
||||
void main() {
|
||||
test('should_return_no_opening_frame_when_thumbnails_url_is_empty', () {
|
||||
expect(playerOpeningFrame(null, posterUrl: ' '), isNull);
|
||||
expect(playerOpeningFrame(' '), isNull);
|
||||
testWidgets('should_return_no_opening_frame_when_thumbnails_is_empty', (
|
||||
tester,
|
||||
) async {
|
||||
final service = SpriteThumbnailAxisService(loader: _FakeSpriteLoader());
|
||||
addTearDown(service.dispose);
|
||||
|
||||
expect(playerOpeningFrame(null, spriteSource: service), isNull);
|
||||
expect(playerOpeningFrame(' ', spriteSource: service), isNull);
|
||||
});
|
||||
|
||||
test('should_keep_opening_frame_when_only_poster_is_available', () {
|
||||
expect(
|
||||
playerOpeningFrame(null, posterUrl: 'https://cdn.test/poster.jpg'),
|
||||
isA<PlayerOpeningFrame>(),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('should_load_and_reuse_first_sprite_frame', (tester) async {
|
||||
testWidgets('should_render_prewarmed_zero_frame_from_shared_cache', (
|
||||
tester,
|
||||
) async {
|
||||
final loader = _FakeSpriteLoader();
|
||||
final cache = OpeningFrameCache();
|
||||
addTearDown(cache.clear);
|
||||
final service = SpriteThumbnailAxisService(loader: loader);
|
||||
addTearDown(service.dispose);
|
||||
const url = 'https://cdn.test/thumbnails.vtt';
|
||||
await service.prepareAt(url, Duration.zero);
|
||||
|
||||
final first = await cache.load(
|
||||
'https://cdn.test/thumbnails.vtt',
|
||||
loader: loader,
|
||||
);
|
||||
final second = await cache.load(
|
||||
'https://cdn.test/thumbnails.vtt',
|
||||
loader: loader,
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: PlayerOpeningFrame(thumbnailsUrl: url, spriteSource: service),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(first, isNotNull);
|
||||
expect(second, same(first));
|
||||
expect(find.byKey(const Key('player-opening-sprite')), findsOneWidget);
|
||||
expect(loader.vttCalls, 1);
|
||||
expect(loader.spriteCalls, ['sprite_001.jpg']);
|
||||
});
|
||||
|
||||
testWidgets('should_render_decoded_opening_frame', (tester) async {
|
||||
final loader = _FakeSpriteLoader();
|
||||
final cache = OpeningFrameCache();
|
||||
addTearDown(cache.clear);
|
||||
testWidgets('should_load_sprite_when_not_prewarmed', (tester) async {
|
||||
final service = SpriteThumbnailAxisService(loader: _FakeSpriteLoader());
|
||||
addTearDown(service.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: PlayerOpeningFrame(
|
||||
thumbnailsUrl: 'https://cdn.test/thumbnails.vtt',
|
||||
loader: loader,
|
||||
cache: cache,
|
||||
spriteSource: service,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -67,80 +65,26 @@ void main() {
|
||||
expect(find.byKey(const Key('player-opening-sprite')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_show_poster_while_sprite_is_loading', (tester) async {
|
||||
final cache = OpeningFrameCache();
|
||||
addTearDown(cache.clear);
|
||||
testWidgets('should_use_same_fit_for_sprite_and_video', (tester) async {
|
||||
final service = SpriteThumbnailAxisService(loader: _FakeSpriteLoader());
|
||||
addTearDown(service.dispose);
|
||||
const url = 'https://cdn.test/thumbnails.vtt';
|
||||
await service.prepareAt(url, Duration.zero);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: PlayerOpeningFrame(
|
||||
thumbnailsUrl: 'https://cdn.test/thumbnails.vtt',
|
||||
posterUrl: 'https://cdn.test/poster.jpg',
|
||||
loader: _FakeSpriteLoader(),
|
||||
cache: cache,
|
||||
thumbnailsUrl: url,
|
||||
spriteSource: service,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byKey(const Key('player-opening-poster')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_use_surface_fit_without_extra_frame_constraint', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: PlayerOpeningFrame(
|
||||
posterUrl: 'https://cdn.test/poster.jpg',
|
||||
),
|
||||
),
|
||||
final preview = tester.widget<SpriteCropPreview>(
|
||||
find.byKey(const Key('player-opening-sprite')),
|
||||
);
|
||||
|
||||
final poster = tester.widget<RemoteImage>(
|
||||
find.byKey(const Key('player-opening-poster')),
|
||||
);
|
||||
|
||||
expect(poster.fit, BoxFit.cover);
|
||||
expect(find.byType(AspectRatio), findsNothing);
|
||||
});
|
||||
|
||||
test('should_forward_video_fit_to_opening_frame', () {
|
||||
final frame = playerOpeningFrame(
|
||||
null,
|
||||
posterUrl: 'https://cdn.test/poster.jpg',
|
||||
fit: BoxFit.contain,
|
||||
);
|
||||
|
||||
expect(frame, isA<PlayerOpeningFrame>());
|
||||
expect((frame! as PlayerOpeningFrame).fit, BoxFit.contain);
|
||||
});
|
||||
|
||||
testWidgets('should_reuse_decoded_sprite_when_parent_rebuilds', (
|
||||
tester,
|
||||
) async {
|
||||
final loader = _FakeSpriteLoader();
|
||||
final cache = OpeningFrameCache();
|
||||
addTearDown(cache.clear);
|
||||
Widget build() => MaterialApp(
|
||||
home: PlayerOpeningFrame(
|
||||
thumbnailsUrl: 'https://cdn.test/thumbnails.vtt',
|
||||
posterUrl: 'https://cdn.test/poster.jpg',
|
||||
loader: loader,
|
||||
cache: cache,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(build());
|
||||
await tester.pumpAndSettle();
|
||||
expect(loader.vttCalls, 1);
|
||||
expect(loader.spriteCalls, hasLength(1));
|
||||
|
||||
await tester.pumpWidget(build());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(loader.vttCalls, 1);
|
||||
expect(loader.spriteCalls, hasLength(1));
|
||||
expect(find.byKey(const Key('player-opening-sprite')), findsOneWidget);
|
||||
expect(preview.fit, BoxFit.contain);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user