// Author: fruit.com.cn import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/theme/app_colors.dart'; import 'package:fruitshorts/core/theme/app_dimens.dart'; import 'package:fruitshorts/core/theme/app_theme.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/mine/mine_types.dart'; import 'package:fruitshorts/pages/mine/widgets/mine_action_grid.dart'; import 'package:fruitshorts/pages/mine/widgets/mine_menu.dart'; const _layoutTolerance = 0.1; const _minimumVipHeight = 110.0; const _premiumVipHeightLimit = 150.0; void main() { testWidgets('should_keep_equal_visible_vip_padding_and_reduce_height', ( tester, ) async { await _pumpLocalized( tester, const SizedBox(width: 342, child: MineVipBanner(onOpen: _noop)), ); final cardRect = tester.getRect(find.byKey(const Key('mine-vip'))); final emblemRect = tester.getRect(find.byKey(const Key('mine-vip-emblem'))); final emblem = tester.widget( find.byKey(const Key('mine-vip-emblem')), ); expect( (emblem.image as AssetImage).assetName, 'assets/icon/vip_membership_badge.png', ); final titleRect = tester.getRect(find.text('VIP')); final benefitsRect = tester.getRect( find.byKey(const Key('mine-vip-benefits')), ); expect(cardRect.height, lessThan(_premiumVipHeightLimit)); expect(cardRect.height, greaterThanOrEqualTo(_minimumVipHeight)); expect( emblemRect.top - cardRect.top, greaterThanOrEqualTo(AppDimens.mineVipPadding), ); expect(benefitsRect.bottom, lessThan(cardRect.bottom)); expect(emblemRect.left, greaterThan(titleRect.right)); final first = tester.getRect(find.byKey(const Key('mine-vip-benefit-0'))); final second = tester.getRect(find.byKey(const Key('mine-vip-benefit-1'))); final third = tester.getRect(find.byKey(const Key('mine-vip-benefit-2'))); expect(first.top, second.top); expect(third.top, greaterThan(first.top)); }); for (final localeTag in ['en', 'id']) { testWidgets( 'should_center_visible_grid_content_when_locale_is_$localeTag', (tester) async { await _pumpLocalized( tester, const MineActionGrid( primaryActions: MinePrimaryActions( onWallet: _noop, onFavorites: _noop, onDownloads: _noop, onHistory: _noop, ), serviceActions: MineServiceActions( onOpen: _ignoreDestination, onLanguage: _noop, ), ), locale: Locale(localeTag), ); for (final action in _actions) { _expectVisibleContentCentered(tester, action); } }, ); } testWidgets('should_use_subtle_dividers_when_rendering_grid', (tester) async { await _pumpLocalized( tester, const MineActionGrid( primaryActions: MinePrimaryActions( onWallet: _noop, onFavorites: _noop, onDownloads: _noop, onHistory: _noop, ), serviceActions: MineServiceActions( onOpen: _ignoreDestination, onLanguage: _noop, ), ), ); final dividers = find.descendant( of: find.byKey(const Key('mine-menu')), matching: find.byWidgetPredicate( (widget) => widget is Container && widget.color == AppColors.mineGridDivider, ), ); expect(dividers, findsNWidgets(7)); expect(AppColors.mineGridDivider, const Color(0x10FFFFFF)); }); } const _actions = [ (Key('mine-wallet'), Key('mine-wallet-icon-surface')), (Key('mine-favorites'), Key('mine-favorites-icon-surface')), (Key('mine-downloads'), Key('mine-downloads-icon-surface')), (Key('mine-history'), Key('mine-history-icon-surface')), (Key('mine-help'), Key('mine-help-icon-surface')), (Key('mine-language'), Key('mine-language-icon-surface')), (Key('mine-settings'), Key('mine-settings-icon-surface')), (Key('mine-notices'), Key('mine-notices-icon-surface')), ]; void _expectVisibleContentCentered(WidgetTester tester, (Key, Key) action) { final cellRect = tester.getRect(find.byKey(action.$1)); final iconRect = tester.getRect(find.byKey(action.$2)); final labelRect = tester.getRect( find.descendant(of: find.byKey(action.$1), matching: find.byType(Text)), ); final visibleRect = Rect.fromLTRB( math.min(iconRect.left, labelRect.left), iconRect.top, math.max(iconRect.right, labelRect.right), labelRect.bottom, ); expect(visibleRect.center.dx, closeTo(cellRect.center.dx, _layoutTolerance)); expect(visibleRect.center.dy, closeTo(cellRect.center.dy, _layoutTolerance)); } Future _pumpLocalized( WidgetTester tester, Widget child, { Locale locale = const Locale('en'), }) async { tester.view.physicalSize = const Size(390, 900); tester.view.devicePixelRatio = 1; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); await tester.pumpWidget( MaterialApp( theme: AppTheme.dark(), locale: locale, supportedLocales: AppLocalizations.supportedLocales, localizationsDelegates: AppLocalizations.localizationsDelegates, home: Scaffold( body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(AppDimens.pageHorizontal), child: child, ), ), ), ), ); await tester.pumpAndSettle(); } void _noop() {} void _ignoreDestination(MineDestination _) {}