529 lines
18 KiB
Dart
529 lines
18 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
testWidgets('Large Badge defaults', (WidgetTester tester) async {
|
|
late final ThemeData theme;
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Builder(
|
|
builder: (BuildContext context) {
|
|
// theme.textTheme is updated when the MaterialApp is built.
|
|
theme = Theme.of(context);
|
|
return const Badge(label: Text('0'), child: Icon(Icons.add));
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(
|
|
tester.renderObject<RenderParagraph>(find.text('0')).text.style,
|
|
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
|
|
);
|
|
|
|
// default badge alignment = AlignmentDirection.topEnd
|
|
// default offset for LTR = Offset(4, -4)
|
|
// default padding = EdgeInsets.symmetric(horizontal: 4)
|
|
// default largeSize = 16
|
|
// '0'.width = 12
|
|
// icon.width = 24
|
|
|
|
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
|
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
|
|
|
expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
|
|
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
final rrect = RRect.fromLTRBR(12, -4, 31.5, 12, const Radius.circular(8));
|
|
expect(box, paints..rrect(rrect: rrect, color: theme.colorScheme.error));
|
|
});
|
|
|
|
testWidgets('Large Badge defaults with RTL', (WidgetTester tester) async {
|
|
late final ThemeData theme;
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Builder(
|
|
builder: (BuildContext context) {
|
|
// theme.textTheme is updated when the MaterialApp is built.
|
|
theme = Theme.of(context);
|
|
return const Badge(label: Text('0'), child: Icon(Icons.add));
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(
|
|
tester.renderObject<RenderParagraph>(find.text('0')).text.style,
|
|
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
|
|
);
|
|
|
|
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
|
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
|
|
|
expect(tester.getTopLeft(find.text('0')), const Offset(0, -4));
|
|
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
final rrect = RRect.fromLTRBR(-4, -4, 15.5, 12, const Radius.circular(8));
|
|
expect(box, paints..rrect(rrect: rrect, color: theme.colorScheme.error));
|
|
});
|
|
|
|
// Essentially the same as 'Large Badge defaults'
|
|
testWidgets('Badge.count', (WidgetTester tester) async {
|
|
late final ThemeData theme;
|
|
|
|
Widget buildFrame(int count) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Builder(
|
|
builder: (BuildContext context) {
|
|
// theme.textTheme is updated when the MaterialApp is built.
|
|
if (count == 0) {
|
|
theme = Theme.of(context);
|
|
}
|
|
return Badge.count(count: count, child: const Icon(Icons.add));
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(0));
|
|
|
|
expect(
|
|
tester.renderObject<RenderParagraph>(find.text('0')).text.style,
|
|
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
|
|
);
|
|
|
|
// default badge alignment = AlignmentDirectional(12, -4)
|
|
// default padding = EdgeInsets.symmetric(horizontal: 4)
|
|
// default largeSize = 16
|
|
// '0'.width = 12
|
|
// icon.width = 24
|
|
|
|
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
|
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
|
|
|
// x = alignment.start + padding.left
|
|
// y = alignment.top
|
|
expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
|
|
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
// '0'.width = 12
|
|
// L = alignment.start
|
|
// T = alignment.top
|
|
// R = L + '0'.width + padding.width
|
|
// B = T + largeSize, R = largeSize/2
|
|
final rrect = RRect.fromLTRBR(12, -4, 31.5, 12, const Radius.circular(8));
|
|
expect(box, paints..rrect(rrect: rrect, color: theme.colorScheme.error));
|
|
|
|
await tester.pumpWidget(buildFrame(1000));
|
|
expect(find.text('999+'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Small Badge defaults', (WidgetTester tester) async {
|
|
final theme = ThemeData();
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: const Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(child: Icon(Icons.add)),
|
|
),
|
|
),
|
|
);
|
|
|
|
// default badge location is end=0, top=0
|
|
// default padding = EdgeInsets.symmetric(horizontal: 4)
|
|
// default smallSize = 6
|
|
// icon.width = 24
|
|
|
|
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
|
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
|
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
// L = icon.size.width - smallSize
|
|
// T = 0
|
|
// R = icon.size.width
|
|
// B = smallSize
|
|
expect(
|
|
box,
|
|
paints..rrect(
|
|
rrect: RRect.fromLTRBR(18, 0, 24, 6, const Radius.circular(3)),
|
|
color: theme.colorScheme.error,
|
|
),
|
|
);
|
|
});
|
|
|
|
testWidgets('Small Badge RTL defaults', (WidgetTester tester) async {
|
|
final theme = ThemeData();
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: const Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(child: Icon(Icons.add)),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// default badge location is end=0, top=0
|
|
// default smallSize = 6
|
|
// icon.width = 24
|
|
|
|
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
|
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
|
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
// L = 0
|
|
// T = 0
|
|
// R = smallSize
|
|
// B = smallSize
|
|
expect(
|
|
box,
|
|
paints..rrect(
|
|
rrect: RRect.fromLTRBR(0, 0, 6, 6, const Radius.circular(3)),
|
|
color: theme.colorScheme.error,
|
|
),
|
|
);
|
|
});
|
|
|
|
testWidgets('Large Badge textStyle and colors', (WidgetTester tester) async {
|
|
final theme = ThemeData();
|
|
const green = Color(0xff00ff00);
|
|
const black = Color(0xff000000);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: const Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(
|
|
textColor: green,
|
|
backgroundColor: black,
|
|
textStyle: TextStyle(fontSize: 10),
|
|
label: Text('0'),
|
|
child: Icon(Icons.add),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final TextStyle textStyle = tester.renderObject<RenderParagraph>(find.text('0')).text.style!;
|
|
expect(textStyle.fontSize, 10);
|
|
expect(textStyle.color, green);
|
|
expect(tester.renderObject(find.byType(Badge)), paints..rrect(color: black));
|
|
});
|
|
|
|
testWidgets('isLabelVisible', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(label: Text('0'), isLabelVisible: false, child: Icon(Icons.add)),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(find.text('0'), findsNothing);
|
|
expect(find.byType(Icon), findsOneWidget);
|
|
|
|
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
|
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
expect(box, isNot(paints..rrect()));
|
|
});
|
|
|
|
testWidgets('Large Badge alignment', (WidgetTester tester) async {
|
|
const badgeRadius = Radius.circular(8);
|
|
|
|
Widget buildFrame(Alignment alignment, [Offset offset = Offset.zero]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(
|
|
// Default largeSize = 16, badge with label is "large".
|
|
label: Container(width: 8, height: 8, color: Colors.blue),
|
|
alignment: alignment,
|
|
offset: offset,
|
|
child: Container(color: const Color(0xFF00FF00), width: 200, height: 200),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topLeft));
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 16, 16, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topCenter));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 0, 100 + 8, 16, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topRight));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 0, 200, 16, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerLeft));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100, 16, 100 + 16, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerRight));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 100, 200, 100 + 16, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomLeft));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200, 16, 200 + 16, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomCenter));
|
|
expect(
|
|
box,
|
|
paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 200, 100 + 8, 200 + 16, badgeRadius)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomRight));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 200, 200, 200 + 16, badgeRadius)));
|
|
|
|
const offset = Offset(5, 10);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topLeft, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 16, 16, badgeRadius).shift(offset)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topCenter, offset));
|
|
expect(
|
|
box,
|
|
paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 0, 100 + 8, 16, badgeRadius).shift(offset)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topRight, offset));
|
|
expect(
|
|
box,
|
|
paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 0, 200, 16, badgeRadius).shift(offset)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerLeft, offset));
|
|
expect(
|
|
box,
|
|
paints..rrect(rrect: RRect.fromLTRBR(0, 100, 16, 100 + 16, badgeRadius).shift(offset)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerRight, offset));
|
|
expect(
|
|
box,
|
|
paints
|
|
..rrect(rrect: RRect.fromLTRBR(200 - 16, 100, 200, 100 + 16, badgeRadius).shift(offset)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomLeft, offset));
|
|
expect(
|
|
box,
|
|
paints..rrect(rrect: RRect.fromLTRBR(0, 200, 16, 200 + 16, badgeRadius).shift(offset)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomCenter, offset));
|
|
expect(
|
|
box,
|
|
paints
|
|
..rrect(rrect: RRect.fromLTRBR(100 - 8, 200, 100 + 8, 200 + 16, badgeRadius).shift(offset)),
|
|
);
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomRight, offset));
|
|
expect(
|
|
box,
|
|
paints
|
|
..rrect(rrect: RRect.fromLTRBR(200 - 16, 200, 200, 200 + 16, badgeRadius).shift(offset)),
|
|
);
|
|
});
|
|
|
|
testWidgets('Small Badge alignment', (WidgetTester tester) async {
|
|
const badgeRadius = Radius.circular(3);
|
|
|
|
Widget buildFrame(Alignment alignment, [Offset offset = Offset.zero]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(
|
|
// Default smallSize = 6, badge without label is "small".
|
|
alignment: alignment,
|
|
offset: offset, // Not used for smallSize badges.
|
|
child: Container(color: const Color(0xFF00FF00), width: 200, height: 200),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topLeft));
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 6, 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topCenter));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 0, 100 + 3, 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topRight));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 0, 200, 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerLeft));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100, 6, 100 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerRight));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 100, 200, 100 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomLeft));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200, 6, 200 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomCenter));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 200, 100 + 3, 200 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomRight));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 200, 200, 200 + 6, badgeRadius)));
|
|
|
|
const offset = Offset(5, 10); // Not used for smallSize Badges.
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topLeft, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 6, 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topCenter, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 0, 100 + 3, 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topRight, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 0, 200, 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerLeft, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100, 6, 100 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.centerRight, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 100, 200, 100 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomLeft, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200, 6, 200 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomCenter, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 200, 100 + 3, 200 + 6, badgeRadius)));
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.bottomRight, offset));
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 200, 200, 200 + 6, badgeRadius)));
|
|
});
|
|
|
|
testWidgets('Badge Larger than large size', (WidgetTester tester) async {
|
|
const badgeRadius = Radius.circular(15);
|
|
|
|
Widget buildFrame(Alignment alignment, [Offset offset = Offset.zero]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge(
|
|
// LargeSize = 16, make content of badge bigger than the default.
|
|
label: Container(width: 30, height: 30, color: Colors.blue),
|
|
alignment: alignment,
|
|
offset: offset,
|
|
child: Container(color: const Color(0xFF00FF00), width: 200, height: 200),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(Alignment.topLeft));
|
|
final RenderBox box = tester.renderObject(find.byType(Badge));
|
|
// Badge should scale with content
|
|
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, -7, 30 + 8, 23, badgeRadius)));
|
|
});
|
|
|
|
testWidgets('Badge renders at zero area', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Center(
|
|
child: SizedBox.shrink(child: Badge(label: Text('X'))),
|
|
),
|
|
),
|
|
);
|
|
final Finder label = find.text('X');
|
|
expect(tester.getSize(label), Size.zero);
|
|
});
|
|
|
|
testWidgets('Badge.count maxCount limits displayed value', (WidgetTester tester) async {
|
|
Widget buildFrame(int count, [int maxCount = 999]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge.count(count: count, maxCount: maxCount, child: const Icon(Icons.add)),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(5, 99));
|
|
expect(find.text('5'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(buildFrame(99, 99));
|
|
expect(find.text('99'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(buildFrame(100, 99));
|
|
expect(find.text('99+'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(buildFrame(999));
|
|
expect(find.text('999'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(buildFrame(1000));
|
|
expect(find.text('999+'), findsOneWidget);
|
|
|
|
// Test default maxCount (999)
|
|
await tester.pumpWidget(buildFrame(1001));
|
|
expect(find.text('999+'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Badge.count asserts on negative count', (WidgetTester tester) async {
|
|
Widget buildFrame(int count, [int maxCount = 999]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge.count(count: count, maxCount: maxCount, child: const Icon(Icons.add)),
|
|
),
|
|
);
|
|
}
|
|
|
|
expect(() => buildFrame(-1), throwsAssertionError);
|
|
});
|
|
|
|
testWidgets('Badge.count asserts on non-positive maxCount', (WidgetTester tester) async {
|
|
Widget buildFrame(int count, [int maxCount = 999]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge.count(count: count, maxCount: maxCount, child: const Icon(Icons.add)),
|
|
),
|
|
);
|
|
}
|
|
|
|
expect(() => buildFrame(5, 0), throwsAssertionError);
|
|
});
|
|
|
|
testWidgets('Badge.count displays "0" when count is zero', (WidgetTester tester) async {
|
|
Widget buildFrame(int count, [int maxCount = 999]) {
|
|
return MaterialApp(
|
|
home: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Badge.count(count: count, maxCount: maxCount, child: const Icon(Icons.add)),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(0, 5));
|
|
expect(find.text('0'), findsOneWidget);
|
|
});
|
|
}
|