Files
ReelShort/test/mine/mine_stats_panel_test.dart

169 lines
5.1 KiB
Dart

// Author: fruit.com.cn
// 验证个人数据图标、无障碍入口与多语言窄屏布局。
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.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/widgets/mine_stat_icon.dart';
import 'package:fruitshorts/pages/mine/widgets/mine_stats_panel.dart';
const _coinsKey = Key('mine-stat-coins');
const _historyKey = Key('mine-stat-watch-records');
const _favoritesKey = Key('mine-stat-favorites');
const _locales = [Locale('zh'), Locale('en'), Locale('id')];
const _widths = [320.0, 390.0];
const _scales = [1.0, 2.0];
const _screenHeight = 600.0;
const _largeBalance = 123456789;
const _historyTotal = 57;
const _favoritesTotal = 23;
void main() {
_responsiveTests();
_interactionTests();
}
void _responsiveTests() {
for (final locale in _locales) {
for (final width in _widths) {
for (final scale in _scales) {
testWidgets(
'should_fit_three_columns_when_${locale.languageCode}_${width}_scale_$scale',
(tester) async {
await _pumpPanel(
tester,
locale: locale,
width: width,
scale: scale,
);
final cells = [_coinsKey, _historyKey, _favoritesKey];
final positions = cells
.map((key) => tester.getTopLeft(find.byKey(key)))
.toList();
expect(positions.map((point) => point.dy).toSet(), hasLength(1));
expect(positions.map((point) => point.dx).toSet(), hasLength(3));
for (final key in cells) {
final size = tester.getSize(find.byKey(key));
expect(size.width, greaterThanOrEqualTo(AppDimens.tapTarget));
expect(size.height, greaterThanOrEqualTo(AppDimens.tapTarget));
}
expect(tester.takeException(), isNull);
},
);
}
}
}
}
void _interactionTests() {
testWidgets(
'should_render_distinct_vector_icons_when_statistics_are_visible',
(tester) async {
await _pumpPanel(tester);
final icons = tester.widgetList<MineStatIcon>(find.byType(MineStatIcon));
expect(icons.map((icon) => icon.type), MineStatIconType.values);
for (final icon in icons) {
expect(
tester.getSize(find.byKey(icon.key!)),
const Size.square(AppDimens.mineStatsIcon),
);
}
},
);
testWidgets('should_forward_each_action_once_when_statistics_are_tapped', (
tester,
) async {
final opened = <MineStatIconType>[];
await _pumpPanel(
tester,
actions: MineStatsActions(
onWallet: () => opened.add(MineStatIconType.coins),
onHistory: () => opened.add(MineStatIconType.history),
onFavorites: () => opened.add(MineStatIconType.favorites),
),
);
for (final key in [_coinsKey, _historyKey, _favoritesKey]) {
await tester.tap(find.byKey(key));
await tester.pump();
}
expect(opened, MineStatIconType.values);
});
testWidgets(
'should_announce_label_value_and_action_when_using_screen_reader',
(tester) async {
await _pumpPanel(tester);
final semantics = tester.ensureSemantics();
final coinSemantics = find.byWidgetPredicate(
(widget) =>
widget is Semantics && widget.properties.label == 'Coin balance',
);
try {
expect(
tester.getSemantics(coinSemantics),
matchesSemantics(
label: 'Coin balance',
value: '123,456,789',
isButton: true,
hasTapAction: true,
),
);
} finally {
semantics.dispose();
}
},
);
}
Future<void> _pumpPanel(
WidgetTester tester, {
Locale locale = const Locale('en'),
double width = 390,
double scale = 1,
MineStatsActions? actions,
}) async {
tester.view.physicalSize = Size(width, _screenHeight);
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,
builder: (context, child) => MediaQuery(
data: MediaQuery.of(
context,
).copyWith(textScaler: TextScaler.linear(scale)),
child: child!,
),
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(AppDimens.pageHorizontal),
child: MineStatsPanel(
coinBalance: _largeBalance,
watchRecordCount: _historyTotal,
favoriteCount: _favoritesTotal,
actions:
actions ??
MineStatsActions(
onWallet: () {},
onHistory: () {},
onFavorites: () {},
),
),
),
),
),
);
await tester.pumpAndSettle();
}