150 lines
4.9 KiB
Dart
150 lines
4.9 KiB
Dart
// Author: fruit.com.cn
|
|
// 职责:验证三种顶部导航接入稳定文字过渡并保留点击与选中语义。
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:fruitshorts/core/data/models/content_category.dart';
|
|
import 'package:fruitshorts/core/widgets/animated_nav_label.dart';
|
|
import 'package:fruitshorts/l10n/app_localizations.dart';
|
|
import 'package:fruitshorts/pages/home/widgets/home_grid_header.dart';
|
|
import 'package:fruitshorts/pages/recommend/recommend_types.dart';
|
|
import 'package:fruitshorts/pages/recommend/widgets/recommend_channel_nav.dart';
|
|
import 'package:fruitshorts/pages/recommend/widgets/recommend_top_nav.dart';
|
|
|
|
const _midpoint = Duration(milliseconds: 90);
|
|
const _duration = Duration(milliseconds: 180);
|
|
const _categories = [
|
|
ContentCategory(id: 'featured', name: '精选'),
|
|
ContentCategory(id: 'new', name: '新剧'),
|
|
];
|
|
const _shortcuts = [
|
|
HomeGridCategoryShortcut(
|
|
label: '精选',
|
|
categoryName: 'featured',
|
|
categoryId: 'featured',
|
|
tab: HomePrimaryTab.featured,
|
|
),
|
|
HomeGridCategoryShortcut(
|
|
label: '新剧',
|
|
categoryName: 'new',
|
|
categoryId: 'new',
|
|
tab: HomePrimaryTab.newReleases,
|
|
),
|
|
];
|
|
|
|
Widget _host(Widget child) => MaterialApp(
|
|
locale: const Locale('zh'),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Scaffold(body: child),
|
|
);
|
|
|
|
double _scale(WidgetTester tester, Finder label) {
|
|
return tester
|
|
.widget<Transform>(
|
|
find.descendant(of: label, matching: find.byType(Transform)),
|
|
)
|
|
.transform
|
|
.entry(0, 0);
|
|
}
|
|
|
|
Future<void> _verifyTransition(
|
|
WidgetTester tester,
|
|
Widget Function(bool) build,
|
|
) async {
|
|
await tester.pumpWidget(_host(build(true)));
|
|
await tester.pumpAndSettle();
|
|
final labels = find.byType(AnimatedNavLabel);
|
|
final rects = [tester.getRect(labels.at(0)), tester.getRect(labels.at(1))];
|
|
await tester.pumpWidget(_host(build(false)));
|
|
await tester.pump(_midpoint);
|
|
expect(_scale(tester, labels.at(0)), inExclusiveRange(0.9, 1.0));
|
|
expect(_scale(tester, labels.at(1)), inExclusiveRange(0.9, 1.0));
|
|
expect(tester.getRect(labels.at(0)), rects[0]);
|
|
expect(tester.getRect(labels.at(1)), rects[1]);
|
|
await tester.pump(_duration);
|
|
expect(tester.getRect(labels.at(1)), rects[1]);
|
|
final semantics = tester.widget<Semantics>(
|
|
find.descendant(of: labels.at(1), matching: find.byType(Semantics)).first,
|
|
);
|
|
expect(semantics.properties.selected, isTrue);
|
|
}
|
|
|
|
void main() {
|
|
testWidgets('should_keep_channel_labels_regular_when_selection_changes', (
|
|
tester,
|
|
) async {
|
|
const categories = [
|
|
ContentCategory(id: 'featured', name: '精选'),
|
|
ContentCategory(id: 'weekly', name: '本周必看'),
|
|
];
|
|
for (final selected in categories) {
|
|
await tester.pumpWidget(
|
|
_host(
|
|
RecommendChannelNav(
|
|
categories: categories,
|
|
selectedId: selected.id,
|
|
onSelected: (_) {},
|
|
onSearch: () {},
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
for (final category in categories) {
|
|
final text = tester.widget<Text>(find.text(category.name));
|
|
expect(text.style?.fontWeight, FontWeight.w400);
|
|
expect(text.style?.fontSize, 17);
|
|
}
|
|
expect(tester.takeException(), isNull);
|
|
}
|
|
});
|
|
|
|
testWidgets('should_keep_home_labels_stable_when_category_changes', (
|
|
tester,
|
|
) async {
|
|
int? tapped;
|
|
HomeGridHeader header(bool first) => HomeGridHeader(
|
|
callbacks: HomeGridCallbacks(
|
|
onSearch: () {},
|
|
onOpenVip: () {},
|
|
onOpenWallet: () {},
|
|
onOpenFilter: () {},
|
|
),
|
|
categories: _shortcuts,
|
|
selectedIndex: first ? 0 : 1,
|
|
onSectionSelected: (index) => tapped = index,
|
|
);
|
|
await _verifyTransition(tester, header);
|
|
await tester.tap(find.byKey(const Key('home-primary-label-new')));
|
|
expect(tapped, 1);
|
|
});
|
|
|
|
testWidgets('should_keep_inner_nav_labels_stable_when_tab_changes', (
|
|
tester,
|
|
) async {
|
|
RecommendInnerTab? tapped;
|
|
RecommendTopNav nav(bool first) => RecommendTopNav(
|
|
selected: first ? RecommendInnerTab.feed : RecommendInnerTab.playlists,
|
|
onSelected: (tab) => tapped = tab,
|
|
onSearch: () {},
|
|
);
|
|
await _verifyTransition(tester, nav);
|
|
await tester.tap(find.byKey(const Key('recommend-tab-playlist')));
|
|
expect(tapped, RecommendInnerTab.playlists);
|
|
});
|
|
|
|
testWidgets('should_keep_channel_labels_stable_when_selection_changes', (
|
|
tester,
|
|
) async {
|
|
String? tapped;
|
|
RecommendChannelNav nav(bool first) => RecommendChannelNav(
|
|
categories: _categories,
|
|
selectedId: first ? 'featured' : 'new',
|
|
onSelected: (id) => tapped = id,
|
|
onSearch: () {},
|
|
);
|
|
await _verifyTransition(tester, nav);
|
|
await tester.tap(find.byKey(const Key('recommend-tab-new')));
|
|
expect(tapped, 'new');
|
|
});
|
|
}
|