169 lines
5.1 KiB
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();
|
|
}
|