refactor(ui): 清理 K26 旧 UI 与死代码
This commit is contained in:
1 parent
a5398daab3
commit
5422581f8b
23 files changed
+291
-1225
No files matched your search
@@ -1,193 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/l10n/app_localizations.dart';
|
||||
import 'package:fruitshorts/pages/discover/widgets/cover_carousel.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
List<CoverItem> items(int count) => [
|
||||
for (var index = 0; index < count; index++)
|
||||
CoverItem(
|
||||
title: 'Banner $index',
|
||||
subtitle: 'Subtitle $index',
|
||||
image: '/files/banner-$index.png',
|
||||
onOpen: _noop,
|
||||
),
|
||||
];
|
||||
|
||||
testWidgets('should_turn_cube_and_keep_title_on_poster_when_carousel_pages', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(
|
||||
_localizedApp(
|
||||
CoverCarousel(
|
||||
items: [
|
||||
for (final title in ['The Signal', 'City Lights', 'Vengeance'])
|
||||
CoverItem(
|
||||
title: title,
|
||||
subtitle: 'Mock',
|
||||
image: '/files/poster.png',
|
||||
onOpen: _noop,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('The Signal'), findsOneWidget);
|
||||
expect(find.text('Mock'), findsOneWidget);
|
||||
|
||||
final box = tester.getRect(find.byType(CoverCarousel));
|
||||
final gesture = await tester.startGesture(
|
||||
Offset(box.right - 40, box.center.dy),
|
||||
);
|
||||
await gesture.moveBy(const Offset(-500, 0));
|
||||
await tester.pump();
|
||||
|
||||
final turned = tester
|
||||
.widgetList<Transform>(find.byType(Transform))
|
||||
.any((transform) => (transform.transform.entry(0, 0) - 1).abs() > 0.15);
|
||||
expect(turned, isTrue);
|
||||
|
||||
await gesture.moveBy(const Offset(-200, 0));
|
||||
await gesture.up();
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 450));
|
||||
|
||||
expect(find.text('City Lights'), findsOneWidget);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('should_auto_advance_and_show_dots_when_multiple_items_exist', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(_localizedApp(CoverCarousel(items: items(3))));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Banner 0'), findsOneWidget);
|
||||
expect(find.byKey(const Key('carousel-dot-0')), findsOneWidget);
|
||||
expect(find.byKey(const Key('carousel-dot-1')), findsOneWidget);
|
||||
expect(find.byKey(const Key('carousel-dot-2')), findsOneWidget);
|
||||
|
||||
await tester.pump(const Duration(milliseconds: 4500));
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(find.text('Banner 1'), findsOneWidget);
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
});
|
||||
|
||||
testWidgets('should_not_schedule_auto_advance_when_only_one_item_exists', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(_localizedApp(CoverCarousel(items: items(1))));
|
||||
await tester.pump(const Duration(seconds: 12));
|
||||
|
||||
expect(find.text('Banner 0'), findsOneWidget);
|
||||
expect(find.byKey(const Key('carousel-dot-0')), findsOneWidget);
|
||||
expect(find.byKey(const Key('carousel-dot-1')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_pause_auto_advance_while_pointer_is_down', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(_localizedApp(CoverCarousel(items: items(3))));
|
||||
await tester.pump();
|
||||
final box = tester.getRect(find.byType(CoverCarousel));
|
||||
final gesture = await tester.startGesture(box.center);
|
||||
await tester.pump(const Duration(seconds: 6));
|
||||
|
||||
expect(find.text('Banner 0'), findsOneWidget);
|
||||
|
||||
await gesture.up();
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 4500));
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(find.text('Banner 1'), findsOneWidget);
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
});
|
||||
|
||||
testWidgets('should_pause_when_inactive_and_resume_when_active_again', (
|
||||
tester,
|
||||
) async {
|
||||
final active = ValueNotifier(false);
|
||||
await tester.pumpWidget(
|
||||
_localizedApp(
|
||||
ValueListenableBuilder<bool>(
|
||||
valueListenable: active,
|
||||
builder: (context, enabled, _) =>
|
||||
CoverCarousel(items: items(2), active: enabled),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump(const Duration(seconds: 6));
|
||||
expect(find.text('Banner 0'), findsOneWidget);
|
||||
|
||||
active.value = true;
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 4500));
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
expect(find.text('Banner 1'), findsOneWidget);
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
});
|
||||
|
||||
testWidgets('should_show_icon_fallback_when_banner_image_is_empty', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(
|
||||
_localizedApp(
|
||||
CoverCarousel(
|
||||
items: const [
|
||||
CoverItem(
|
||||
title: 'Broken image',
|
||||
subtitle: '',
|
||||
image: '',
|
||||
onOpen: _noop,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byKey(const Key('carousel-image-fallback')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'should_keep_existing_open_callback_when_active_poster_is_tapped',
|
||||
(tester) async {
|
||||
var opened = 0;
|
||||
await tester.pumpWidget(
|
||||
_localizedApp(
|
||||
CoverCarousel(
|
||||
items: [
|
||||
CoverItem(
|
||||
title: 'Tap me',
|
||||
subtitle: '',
|
||||
image: '/files/banner.png',
|
||||
onOpen: () => opened++,
|
||||
),
|
||||
...items(1),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
await tester.tap(find.text('Tap me'));
|
||||
expect(opened, 1);
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _noop() {}
|
||||
|
||||
Widget _localizedApp(Widget child) => MaterialApp(
|
||||
locale: const Locale('en'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
@@ -38,7 +38,6 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Continue Watching'), findsNothing);
|
||||
expect(find.byKey(const Key('home-all-dramas-title')), findsNothing);
|
||||
expect(find.text('Recommended'), findsOneWidget);
|
||||
expect(find.text('For You'), findsNothing);
|
||||
final grid = tester.widget<SliverGrid>(
|
||||
@@ -133,7 +132,6 @@ void main() {
|
||||
await tester.tap(find.byKey(const Key('tab-discover')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('home-all-dramas-title')), findsNothing);
|
||||
expect(find.text('No matching dramas.'), findsOneWidget);
|
||||
expect(find.byKey(const Key('empty-state-content')), findsOneWidget);
|
||||
|
||||
@@ -153,7 +151,6 @@ void main() {
|
||||
await tester.tap(find.byKey(const Key('tab-discover')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('home-all-dramas-title')), findsNothing);
|
||||
expect(find.text('Categories could not be loaded.'), findsOneWidget);
|
||||
expect(find.text('Retry'), findsOneWidget);
|
||||
expect(find.byKey(const Key('empty-state-icon')), findsOneWidget);
|
||||
@@ -179,7 +176,6 @@ void main() {
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('home-all-dramas-title')), findsNothing);
|
||||
expect(find.text('City Lights & Velvet Nights'), findsWidgets);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/app.dart';
|
||||
import 'package:fruitshorts/core/data/models/drama.dart';
|
||||
import 'package:fruitshorts/core/data/models/home_feed.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/catalog_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
||||
import 'package:fruitshorts/pages/discover/widgets/cover_carousel.dart';
|
||||
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
||||
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
||||
|
||||
import '../support/fake_catalog.dart';
|
||||
import '../support/fake_category.dart';
|
||||
import '../support/fake_interaction_repositories.dart';
|
||||
import '../support/fake_notice_repository.dart';
|
||||
import '../support/widget_player.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets(
|
||||
'should_not_mount_carousel_on_discover_even_when_home_banners_exist',
|
||||
(tester) async {
|
||||
SharedPreferencesAsyncPlatform.instance =
|
||||
InMemorySharedPreferencesAsync.empty();
|
||||
final catalog = _HomeBannerCatalogRepository();
|
||||
await tester.pumpWidget(
|
||||
LumaDramaApp(
|
||||
playerFactory: createWidgetPlayer,
|
||||
catalogRepository: catalog,
|
||||
categoryRepository: FakeCategoryRepository(catalog: catalog),
|
||||
watchHistoryRepository: InMemoryWatchHistoryRepository(),
|
||||
favoriteRepository: InMemoryFavoriteRepository(),
|
||||
playbackRepository: FakePlaybackRepository(),
|
||||
commentRepository: FakeCommentRepository(),
|
||||
interactionRepository: FakeInteractionRepository(),
|
||||
noticeRepository: FakeNoticeRepository(),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('tab-discover')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CoverCarousel), findsNothing);
|
||||
expect(find.byKey(const Key('discover-search')), findsOneWidget);
|
||||
expect(find.byKey(const Key('home-all-dramas-grid')), findsOneWidget);
|
||||
expect(find.byKey(const Key('discover-quick-filter')), findsOneWidget);
|
||||
expect(find.text('The Signal'), findsWidgets);
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class _HomeBannerCatalogRepository implements CatalogRepository {
|
||||
final _delegate = FakeCatalogRepository();
|
||||
|
||||
@override
|
||||
Future<HomeFeed> fetchHomeFeed() async => HomeFeed(
|
||||
banners: const [
|
||||
FeedBanner(
|
||||
id: 'banner-1',
|
||||
imageUrl: '/files/banner-1.png',
|
||||
linkType: 'DRAMA',
|
||||
linkValue: 'the-signal-demo',
|
||||
),
|
||||
FeedBanner(
|
||||
id: 'banner-2',
|
||||
imageUrl: '/files/banner-2.png',
|
||||
linkType: 'DRAMA',
|
||||
linkValue: 'city-lights-demo',
|
||||
),
|
||||
],
|
||||
sections: [FeedSection(code: 'hot', title: 'Hot', dramas: demoDramas)],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<HomeFeed> fetchDiscoverFeed() async => HomeFeed(
|
||||
sections: [FeedSection(code: 'hot', title: 'Hot', dramas: demoDramas)],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<Drama> fetchDrama(String dramaId) => _delegate.fetchDrama(dramaId);
|
||||
}
|
||||
Reference in new issue
Block a user