Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/flutter/test/foundation/leak_tracking.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ class LeakCleaner {

/// Returns true if [leak] should be reported as failure.
bool _shouldReportLeak(LeakType leakType, LeakReport leak, Map<(String, LeakType), int> countByClassAndType) {
switch (leakType) {
case LeakType.notDisposed:
if (config.allowAllNotDisposed) {
return false;
}
case LeakType.notGCed:
case LeakType.gcedLate:
if (config.allowAllNotGCed) {
return false;
}
}

final String leakingClass = leak.type;
final (String, LeakType) classAndType = (leakingClass, leakType);

Expand Down
34 changes: 30 additions & 4 deletions packages/flutter/test/foundation/leak_tracking_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,28 @@ Future<void> main() async {
),
);

testWidgetsWithLeakTracking(
'respects allowAllNotDisposed',
(WidgetTester tester) async {
// ignore: avoid_redundant_argument_values, for readability.
await tester.pumpWidget(_StatelessLeakingWidget(notDisposed: true, notGCed: false));
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
),
);

testWidgetsWithLeakTracking(
'respects allowAllNotGCed',
(WidgetTester tester) async {
// ignore: avoid_redundant_argument_values, for readability.
await tester.pumpWidget(_StatelessLeakingWidget(notDisposed: false, notGCed: true));
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotGCed: true,
),
);

testWidgetsWithLeakTracking(
'respects count in allow lists',
(WidgetTester tester) async {
Expand Down Expand Up @@ -180,10 +202,14 @@ void _verifyLeakList(List<LeakReport> list, int expectedCount, bool shouldContai
final List<_LeakTrackedClass> _notGcedStorage = <_LeakTrackedClass>[];

class _StatelessLeakingWidget extends StatelessWidget {
_StatelessLeakingWidget() {
// ignore: unused_local_variable, the variable is used to create non disposed leak
final _LeakTrackedClass notDisposed = _LeakTrackedClass();
_notGcedStorage.add(_LeakTrackedClass()..dispose());
_StatelessLeakingWidget({bool notDisposed = true, bool notGCed = true}) {
if (notDisposed) {
// ignore: unused_local_variable, the variable is used to create non disposed leak
final _LeakTrackedClass notDisposed = _LeakTrackedClass();
}
if (notGCed) {
_notGcedStorage.add(_LeakTrackedClass()..dispose());
}
}

@override
Expand Down
10 changes: 8 additions & 2 deletions packages/flutter/test/material/date_range_picker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import '../foundation/leak_tracking.dart';
import 'feedback_tester.dart';

void main() {
Expand Down Expand Up @@ -250,12 +251,17 @@ void main() {
await tester.pumpAndSettle();
});

testWidgets('landscape', (WidgetTester tester) async {
testWidgetsWithLeakTracking('landscape', (WidgetTester tester) async {
await showPicker(tester, kCommonScreenSizeLandscape);
expect(tester.widget<Text>(find.text('Jan 15 – Jan 25, 2016')).style?.fontSize, 24);
await tester.tap(find.text('Cancel'));
await tester.pumpAndSettle();
});
},
// TODO(polina-c): remove after resolving
// https://github.com/flutter/flutter/issues/130354
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotGCed: true,
));
});

testWidgets('Save and help text is used', (WidgetTester tester) async {
Expand Down
16 changes: 14 additions & 2 deletions packages/flutter/test/material/text_selection_theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import '../foundation/leak_tracking.dart';
import '../rendering/mock_canvas.dart';

void main() {
Expand Down Expand Up @@ -59,7 +60,7 @@ void main() {
]);
});

testWidgets('Empty textSelectionTheme will use defaults', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Empty textSelectionTheme will use defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
final Color defaultCursorColor = material3 ? theme.colorScheme.primary : const Color(0xff2196f3);
Expand Down Expand Up @@ -106,7 +107,18 @@ void main() {
await tester.pumpAndSettle();
final RenderBox handle = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint));
expect(handle, paints..path(color: defaultSelectionHandleColor));
});
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/130469
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'ValueNotifier<MagnifierInfo>': 1,
'ValueNotifier<_OverlayEntryWidgetState?>': 2,
'ValueNotifier<bool>': 1,
},
// TODO(polina-c): investigate notGCed, if it does not disappear after fixing notDisposed.
allowAllNotGCed: true,
));

testWidgets('ThemeData.textSelectionTheme will be used if provided', (WidgetTester tester) async {
const TextSelectionThemeData textSelectionTheme = TextSelectionThemeData(
Expand Down