197 lines
6.0 KiB
Dart
197 lines
6.0 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:fruitshorts/core/data/models/drama.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/home/widgets/home_feed_card.dart';
|
|
|
|
void main() {
|
|
testWidgets('should_render_grid_card_cover_badge_views_title_and_tags', (
|
|
tester,
|
|
) async {
|
|
var taps = 0;
|
|
await _pumpCard(
|
|
tester,
|
|
drama: _drama(
|
|
id: 'anime-card',
|
|
title: 'A very long home grid drama title that must wrap',
|
|
dramaType: 'ANIME',
|
|
viewCount: 444500,
|
|
),
|
|
onTap: () => taps++,
|
|
);
|
|
|
|
final card = find.byKey(const Key('home-feed-card-anime-card'));
|
|
expect(tester.widget<Material>(card).color, AppColors.transparent);
|
|
expect(
|
|
tester
|
|
.widgetList<Container>(
|
|
find.descendant(of: card, matching: find.byType(Container)),
|
|
)
|
|
.map((container) => container.decoration)
|
|
.whereType<BoxDecoration>()
|
|
.every((decoration) => decoration.border == null),
|
|
isTrue,
|
|
);
|
|
|
|
final cover = find.byKey(const Key('home-feed-cover-anime-card'));
|
|
final coverSize = tester.getSize(cover);
|
|
expect(coverSize.height / coverSize.width, closeTo(6 / 5, 0.02));
|
|
final coverClip = tester.widget<ClipRRect>(
|
|
find.byKey(const Key('home-feed-cover-clip-anime-card')),
|
|
);
|
|
expect(
|
|
coverClip.borderRadius,
|
|
BorderRadius.circular(AppDimens.cardCoverRadius),
|
|
);
|
|
final badge = find.byKey(const Key('home-feed-badge-anime-anime-card'));
|
|
expect(badge, findsOneWidget);
|
|
final badgeContainer = tester.widget<Container>(badge);
|
|
expect(
|
|
(badgeContainer.decoration! as BoxDecoration).borderRadius,
|
|
BorderRadius.circular(AppDimens.cardBadgeRadius),
|
|
);
|
|
expect(
|
|
tester
|
|
.widget<Text>(find.descendant(of: badge, matching: find.byType(Text)))
|
|
.style
|
|
?.fontSize,
|
|
AppDimens.cardBadgeFont,
|
|
);
|
|
expect(find.text('Anime'), findsOneWidget);
|
|
expect(find.byKey(const Key('home-feed-views-anime-card')), findsOneWidget);
|
|
final views = find.byKey(const Key('home-feed-views-anime-card'));
|
|
final viewsText = tester.widget<Text>(
|
|
find.descendant(of: views, matching: find.byType(Text)),
|
|
);
|
|
expect(viewsText.data, '44.5w');
|
|
expect(viewsText.style?.fontSize, AppDimens.cardViewsFont);
|
|
expect(viewsText.style?.color, AppColors.navSelected);
|
|
expect(
|
|
find.descendant(
|
|
of: views,
|
|
matching: find.byIcon(Icons.auto_awesome_rounded),
|
|
),
|
|
findsOneWidget,
|
|
);
|
|
final title = tester.widget<Text>(
|
|
find.byKey(const Key('home-feed-title-anime-card')),
|
|
);
|
|
expect(title.maxLines, 2);
|
|
expect(title.style?.fontSize, AppDimens.cardTitleFont);
|
|
expect(title.style?.fontWeight, FontWeight.w500);
|
|
expect(title.style?.height, AppDimens.cardTitleLineHeight);
|
|
final ribbon = find.byKey(const Key('drama-genre-ribbon-anime-card-0'));
|
|
expect(ribbon, findsOneWidget);
|
|
final ribbonText = tester.widget<Text>(
|
|
find.descendant(of: ribbon, matching: find.byType(Text)),
|
|
);
|
|
expect(ribbonText.data, 'Romance');
|
|
expect(ribbonText.style?.fontSize, AppDimens.cardBadgeFont);
|
|
expect(ribbonText.style?.color, AppColors.textPrimary);
|
|
expect(tester.getTopLeft(title).dx, tester.getTopLeft(cover).dx);
|
|
|
|
await tester.tap(card);
|
|
expect(taps, 1);
|
|
});
|
|
|
|
testWidgets('should_choose_anime_new_and_hot_badges_from_real_data', (
|
|
tester,
|
|
) async {
|
|
final now = DateTime(2026, 10, 22, 12);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: AppTheme.dark(),
|
|
locale: const Locale('en'),
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
home: Scaffold(
|
|
body: Row(
|
|
children: [
|
|
for (final drama in [
|
|
_drama(id: 'anime', title: 'Anime', dramaType: 'ANIME'),
|
|
_drama(
|
|
id: 'new',
|
|
title: 'New',
|
|
createdAt: now.subtract(const Duration(days: 2)),
|
|
),
|
|
_drama(id: 'hot', title: 'Hot', isHot: true),
|
|
])
|
|
SizedBox(
|
|
width: 130,
|
|
height: 240,
|
|
child: HomeFeedCard(drama: drama, onTap: () {}, now: now),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(
|
|
find.byKey(const Key('home-feed-badge-anime-anime')),
|
|
findsOneWidget,
|
|
);
|
|
expect(
|
|
find.byKey(const Key('home-feed-badge-newRelease-new')),
|
|
findsOneWidget,
|
|
);
|
|
expect(find.byKey(const Key('home-feed-badge-hot-hot')), findsOneWidget);
|
|
});
|
|
}
|
|
|
|
Drama _drama({
|
|
required String id,
|
|
required String title,
|
|
String dramaType = 'LIVE',
|
|
int viewCount = 0,
|
|
bool isHot = false,
|
|
DateTime? createdAt,
|
|
}) {
|
|
return Drama(
|
|
id: id,
|
|
title: title,
|
|
synopsis: 'synopsis',
|
|
posterUrl: '/files/$id.jpg',
|
|
genre: 'Romance',
|
|
category: 'Urban',
|
|
viewCount: viewCount,
|
|
isHot: isHot,
|
|
dramaType: dramaType,
|
|
createdAt: createdAt,
|
|
);
|
|
}
|
|
|
|
Future<void> _pumpCard(
|
|
WidgetTester tester, {
|
|
required Drama drama,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: AppTheme.dark(),
|
|
locale: const Locale('en'),
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: SizedBox(
|
|
width: 130,
|
|
height: 240,
|
|
child: HomeFeedCard(
|
|
drama: drama,
|
|
onTap: onTap,
|
|
now: DateTime(2026, 10, 22, 12),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|