// Author: fruit.com.cn // 职责:验证首页三标签文字和下划线随页面进度连续变化。 import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/theme/app_colors.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/recommend/recommend_types.dart'; import 'package:fruitshorts/pages/recommend/widgets/recommend_top_nav.dart'; const _pagePosition = 0.35; const _duration = Duration(milliseconds: 90); const _epsilon = 0.0001; Widget _host({ double? position, RecommendInnerTab tab = RecommendInnerTab.feed, }) { return MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: Scaffold( body: RecommendTopNav( selected: tab, pagePosition: position, onSelected: (_) {}, onSearch: () {}, ), ), ); } double _scale(WidgetTester tester, String tab) => tester .widget( find.descendant( of: find.byKey(Key('recommend-tab-$tab')), matching: find.byType(Transform), ), ) .transform .entry(0, 0); Color _underline(WidgetTester tester, String tab) { final line = tester.widget( find.byKey(Key('recommend-tab-$tab-underline')), ); return (line.decoration! as BoxDecoration).color!; } void main() { testWidgets( 'should_brighten_only_inactive_home_tabs_when_selection_changes', (tester) async { const inactive = Color(0xFFC7C7CC); const codes = ['recommend', 'playlist', 'all']; for (final tab in RecommendInnerTab.values) { await tester.pumpWidget( _host(position: tab.index.toDouble(), tab: tab), ); for (final (index, code) in codes.indexed) { final text = tester.widget( find.descendant( of: find.byKey(Key('recommend-tab-$code')), matching: find.byType(Text), ), ); expect( text.style?.color, index == tab.index ? AppColors.textPrimary : inactive, ); } } await tester.pumpWidget(_host(position: _pagePosition)); final text = tester.widget( find.descendant( of: find.byKey(const Key('recommend-tab-playlist')), matching: find.byType(Text), ), ); expect( text.style?.color, Color.lerp(inactive, AppColors.textPrimary, _pagePosition), ); expect(AppColors.textTabInactive, const Color(0xFFB0B0B0)); }, ); testWidgets('should_keep_regular_enlarged_labels_for_every_selection', ( tester, ) async { for (final tab in RecommendInnerTab.values) { await tester.pumpWidget(_host(position: tab.index.toDouble(), tab: tab)); for (final code in ['recommend', 'playlist', 'all']) { final text = tester.widget( find.descendant( of: find.byKey(Key('recommend-tab-$code')), matching: find.byType(Text), ), ); expect(text.style?.fontSize, 18); expect(text.style?.fontWeight, FontWeight.w400); } expect(tester.takeException(), isNull); } }); testWidgets('should_follow_page_position_without_delayed_label_animation', ( tester, ) async { await tester.pumpWidget(_host(position: 0)); final first = tester.getRect( find.byKey(const Key('recommend-tab-recommend')), ); final second = tester.getRect( find.byKey(const Key('recommend-tab-playlist')), ); await tester.pumpWidget( _host(position: _pagePosition, tab: RecommendInnerTab.playlists), ); expect(_scale(tester, 'recommend'), closeTo(0.965, _epsilon)); expect(_scale(tester, 'playlist'), closeTo(0.935, _epsilon)); expect(_underline(tester, 'recommend').a, closeTo(0.65, _epsilon)); expect(_underline(tester, 'playlist').a, closeTo(0.35, _epsilon)); expect(_underline(tester, 'all').a, 0); expect( tester.getRect(find.byKey(const Key('recommend-tab-recommend'))), first, ); expect( tester.getRect(find.byKey(const Key('recommend-tab-playlist'))), second, ); await tester.pumpWidget(_host(position: 0)); expect(_scale(tester, 'recommend'), 1); expect(_underline(tester, 'recommend'), AppColors.brandRed); }); testWidgets('should_fade_both_underlines_when_used_without_page_position', ( tester, ) async { await tester.pumpWidget(_host()); await tester.pumpWidget(_host(tab: RecommendInnerTab.playlists)); await tester.pump(_duration); expect(_underline(tester, 'recommend').a, inExclusiveRange(0.0, 1.0)); expect(_underline(tester, 'playlist').a, inExclusiveRange(0.0, 1.0)); }); }