Unpin leak_tracker and handle breaking changes in API. (#132352)

This commit is contained in:
Polina Cherkasova 2023-08-14 10:05:20 -07:00 committed by GitHub
parent 87de2c5e60
commit a7b69b069f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
142 changed files with 666 additions and 1048 deletions

View File

@ -22,8 +22,8 @@ dev_dependencies:
flutter_goldens: flutter_goldens:
sdk: flutter sdk: flutter
fake_async: 1.3.1 fake_async: 1.3.1
leak_tracker: 8.0.3 leak_tracker: 9.0.4
leak_tracker_testing: 1.0.2 leak_tracker_flutter_testing: 1.0.1
_fe_analyzer_shared: 63.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" _fe_analyzer_shared: 63.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
analyzer: 6.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" analyzer: 6.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@ -42,6 +42,7 @@ dev_dependencies:
intl: 0.18.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.18.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
leak_tracker_testing: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@ -73,4 +74,4 @@ dev_dependencies:
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 443a # PUBSPEC CHECKSUM: a63c

View File

@ -12,7 +12,6 @@ import 'dart:ui' as ui;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
/* /*
@ -20,7 +19,7 @@ void main() {
* because [matchesGoldenFile] does not use Skia Gold in its native package. * because [matchesGoldenFile] does not use Skia Gold in its native package.
*/ */
testWidgetsWithLeakTracking('correctly records frames using collate', (WidgetTester tester) async { testWidgets('correctly records frames using collate', (WidgetTester tester) async {
final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size); final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
await tester.pumpFrames( await tester.pumpFrames(
@ -57,7 +56,7 @@ void main() {
image.dispose(); image.dispose();
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001
testWidgetsWithLeakTracking('use allLayers to record out-of-subtree contents', (WidgetTester tester) async { testWidgets('use allLayers to record out-of-subtree contents', (WidgetTester tester) async {
final AnimationSheetBuilder builder = AnimationSheetBuilder( final AnimationSheetBuilder builder = AnimationSheetBuilder(
frameSize: const Size(8, 2), frameSize: const Size(8, 2),
allLayers: true, allLayers: true,

View File

@ -5,8 +5,7 @@
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('awaiting animation controllers - using direct future', (WidgetTester tester) async { testWidgetsWithLeakTracking('awaiting animation controllers - using direct future', (WidgetTester tester) async {

View File

@ -4,8 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
setUp(() { setUp(() {

View File

@ -11,8 +11,7 @@ import 'dart:ui' as ui;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
/* /*
@ -80,7 +79,7 @@ void main() {
// Currently skipped due to daily flake: https://github.com/flutter/flutter/issues/87588 // Currently skipped due to daily flake: https://github.com/flutter/flutter/issues/87588
}, skip: true); // Typically skip: isBrowser https://github.com/flutter/flutter/issues/42767 }, skip: true); // Typically skip: isBrowser https://github.com/flutter/flutter/issues/42767
testWidgetsWithLeakTracking('Should show event indicator for pointer events with setSurfaceSize', (WidgetTester tester) async { testWidgets('Should show event indicator for pointer events with setSurfaceSize', (WidgetTester tester) async {
final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(200, 200), allLayers: true); final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(200, 200), allLayers: true);
final List<Offset> taps = <Offset>[]; final List<Offset> taps = <Offset>[];
Widget target({bool recording = true}) => Container( Widget target({bool recording = true}) => Container(

View File

@ -7,6 +7,7 @@ import 'dart:async';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker/leak_tracker.dart'; import 'package:leak_tracker/leak_tracker.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '_goldens_io.dart' import '_goldens_io.dart'
if (dart.library.html) '_goldens_web.dart' as flutter_goldens; if (dart.library.html) '_goldens_web.dart' as flutter_goldens;
@ -23,7 +24,10 @@ Future<void> testExecutable(FutureOr<void> Function() testMain) {
// receive the event. // receive the event.
WidgetController.hitTestWarningShouldBeFatal = true; WidgetController.hitTestWarningShouldBeFatal = true;
LeakTrackerGlobalSettings.warnForNonSupportedPlatforms = false; LeakTracking.warnForUnsupportedPlatforms = false;
setLeakTrackingTestSettings(
LeakTrackingTestSettings(switches: const Switches(disableNotGCed: true))
);
// Enable golden file testing using Skia Gold. // Enable golden file testing using Skia Gold.
return flutter_goldens.testExecutable(testMain); return flutter_goldens.testExecutable(testMain);

View File

@ -4,8 +4,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'leak_tracking.dart';
class TestNotifier extends ChangeNotifier { class TestNotifier extends ChangeNotifier {
void notify() { void notify() {

View File

@ -1,206 +0,0 @@
// 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 'dart:core';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker/leak_tracker.dart';
import 'package:leak_tracker_testing/leak_tracker_testing.dart';
import 'package:meta/meta.dart';
export 'package:leak_tracker/leak_tracker.dart' show LeakDiagnosticConfig, LeakTrackingTestConfig;
/// Set of objects, that does not hold the objects from garbage collection.
///
/// The objects are referenced by hash codes and can duplicate with low probability.
@visibleForTesting
class WeakSet {
final Set<String> _objectCodes = <String>{};
String _toCode(int hashCode, String type) => '$type-$hashCode';
void add(Object object) {
_objectCodes.add(_toCode(identityHashCode(object), object.runtimeType.toString()));
}
void addByCode(int hashCode, String type) {
_objectCodes.add(_toCode(hashCode, type));
}
bool contains(int hashCode, String type) {
final bool result = _objectCodes.contains(_toCode(hashCode, type));
return result;
}
}
/// Wrapper for [testWidgets] with memory leak tracking.
///
/// The method will fail if instrumented objects in [callback] are
/// garbage collected without being disposed.
///
/// More about leak tracking:
/// https://github.com/dart-lang/leak_tracker.
///
/// See https://github.com/flutter/devtools/issues/3951 for plans
/// on leak tracking.
@isTest
void testWidgetsWithLeakTracking(
String description,
WidgetTesterCallback callback, {
bool? skip,
Timeout? timeout,
bool semanticsEnabled = true,
TestVariant<Object?> variant = const DefaultTestVariant(),
dynamic tags,
LeakTrackingTestConfig leakTrackingTestConfig = const LeakTrackingTestConfig(),
}) {
Future<void> wrappedCallback(WidgetTester tester) async {
await _withFlutterLeakTracking(
() async => callback(tester),
tester,
leakTrackingTestConfig,
);
}
testWidgets(
description,
wrappedCallback,
skip: skip,
timeout: timeout,
semanticsEnabled: semanticsEnabled,
variant: variant,
tags: tags,
);
}
bool _webWarningPrinted = false;
/// Runs [callback] with leak tracking.
///
/// Wrapper for [withLeakTracking] with Flutter specific functionality.
///
/// The method will fail if wrapped code contains memory leaks.
///
/// See details in documentation for `withLeakTracking` at
/// https://github.com/dart-lang/leak_tracker/blob/main/lib/src/leak_tracking/orchestration.dart
///
/// The Flutter related enhancements are:
/// 1. Listens to [MemoryAllocations] events.
/// 2. Uses `tester.runAsync` for leak detection if [tester] is provided.
///
/// Pass [config] to troubleshoot or exempt leaks. See [LeakTrackingTestConfig]
/// for details.
Future<void> _withFlutterLeakTracking(
DartAsyncCallback callback,
WidgetTester tester,
LeakTrackingTestConfig config,
) async {
// Leak tracker does not work for web platform.
if (kIsWeb) {
final bool shouldPrintWarning = !_webWarningPrinted && LeakTrackerGlobalSettings.warnForNonSupportedPlatforms;
if (shouldPrintWarning) {
_webWarningPrinted = true;
debugPrint('Leak tracking is not supported on web platform.\nTo turn off this message, set `LeakTrackingTestConfig.warnForNonSupportedPlatforms` to false.');
}
await callback();
return;
}
void flutterEventToLeakTracker(ObjectEvent event) {
return dispatchObjectEvent(event.toMap());
}
return TestAsyncUtils.guard<void>(() async {
MemoryAllocations.instance.addListener(flutterEventToLeakTracker);
Future<void> asyncCodeRunner(DartAsyncCallback action) async => tester.runAsync(action);
try {
Leaks leaks = await withLeakTracking(
callback,
asyncCodeRunner: asyncCodeRunner,
leakDiagnosticConfig: config.leakDiagnosticConfig,
shouldThrowOnLeaks: false,
);
leaks = LeakCleaner(config).clean(leaks);
if (leaks.total > 0) {
config.onLeaks?.call(leaks);
if (config.failTestOnLeaks) {
expect(leaks, isLeakFree);
}
}
} finally {
MemoryAllocations.instance.removeListener(flutterEventToLeakTracker);
}
});
}
/// Cleans leaks that are allowed by [config].
@visibleForTesting
class LeakCleaner {
LeakCleaner(this.config);
final LeakTrackingTestConfig config;
static Map<(String, LeakType), int> _countByClassAndType(Leaks leaks) {
final Map<(String, LeakType), int> result = <(String, LeakType), int>{};
for (final MapEntry<LeakType, List<LeakReport>> entry in leaks.byType.entries) {
for (final LeakReport leak in entry.value) {
final (String, LeakType) classAndType = (leak.type, entry.key);
result[classAndType] = (result[classAndType] ?? 0) + 1;
}
}
return result;
}
Leaks clean(Leaks leaks) {
final Map<(String, LeakType), int> countByClassAndType = _countByClassAndType(leaks);
final Leaks result = Leaks(<LeakType, List<LeakReport>>{
for (final LeakType leakType in leaks.byType.keys)
leakType: leaks.byType[leakType]!.where((LeakReport leak) => _shouldReportLeak(leakType, leak, countByClassAndType)).toList()
});
return result;
}
/// 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);
bool isAllowedForClass(Map<String, int?> allowList) {
if (!allowList.containsKey(leakingClass)) {
return false;
}
final int? allowedCount = allowList[leakingClass];
if (allowedCount == null) {
return true;
}
return allowedCount >= countByClassAndType[classAndType]!;
}
switch (leakType) {
case LeakType.notDisposed:
return !isAllowedForClass(config.notDisposedAllowList);
case LeakType.notGCed:
case LeakType.gcedLate:
return !isAllowedForClass(config.notGCedAllowList);
}
}
}

View File

@ -1,235 +0,0 @@
// 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/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker/leak_tracker.dart';
import 'package:leak_tracker_testing/leak_tracker_testing.dart';
import 'leak_tracking.dart';
final String _leakTrackedClassName = '$_LeakTrackedClass';
Leaks _leaksOfAllTypes() => Leaks(<LeakType, List<LeakReport>> {
LeakType.notDisposed: <LeakReport>[LeakReport(code: 1, context: <String, dynamic>{}, type:'myNotDisposedClass', trackedClass: 'myTrackedClass')],
LeakType.notGCed: <LeakReport>[LeakReport(code: 2, context: <String, dynamic>{}, type:'myNotGCedClass', trackedClass: 'myTrackedClass')],
LeakType.gcedLate: <LeakReport>[LeakReport(code: 3, context: <String, dynamic>{}, type:'myGCedLateClass', trackedClass: 'myTrackedClass')],
});
Future<void> main() async {
test('Trivial $LeakCleaner returns all leaks.', () {
final LeakCleaner leakCleaner = LeakCleaner(const LeakTrackingTestConfig());
final Leaks leaks = _leaksOfAllTypes();
final int leakTotal = leaks.total;
final Leaks cleanedLeaks = leakCleaner.clean(leaks);
expect(leaks.total, leakTotal);
expect(cleanedLeaks.total, 3);
});
test('$LeakCleaner catches extra leaks', () {
Leaks leaks = _leaksOfAllTypes();
final LeakReport leak = leaks.notDisposed.first;
leaks.notDisposed.add(leak);
final LeakTrackingTestConfig config = LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{leak.type: 1},
);
leaks = LeakCleaner(config).clean(leaks);
expect(leaks.notDisposed, hasLength(2));
});
group('Leak tracking works for non-web, and', () {
testWidgetsWithLeakTracking(
'respects all allow lists',
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
leakTrackingTestConfig: LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{_leakTrackedClassName: null},
notGCedAllowList: <String, int?>{_leakTrackedClassName: null},
),
);
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 {
await tester.pumpWidget(_StatelessLeakingWidget());
},
leakTrackingTestConfig: LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{_leakTrackedClassName: 1},
notGCedAllowList: <String, int?>{_leakTrackedClassName: 1},
),
);
group('fails if number or leaks is more than allowed', () {
// This test cannot run inside other tests because test nesting is forbidden.
// So, `expect` happens outside the tests, in `tearDown`.
late Leaks leaks;
testWidgetsWithLeakTracking(
'for $_StatelessLeakingWidget',
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
await tester.pumpWidget(_StatelessLeakingWidget());
},
leakTrackingTestConfig: LeakTrackingTestConfig(
onLeaks: (Leaks theLeaks) {
leaks = theLeaks;
},
failTestOnLeaks: false,
notDisposedAllowList: <String, int?>{_leakTrackedClassName: 1},
),
);
tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 2, expectedNotGCed: 2, shouldContainDebugInfo: false));
});
group('respects notGCed allow lists', () {
// These tests cannot run inside other tests because test nesting is forbidden.
// So, `expect` happens outside the tests, in `tearDown`.
late Leaks leaks;
testWidgetsWithLeakTracking(
'when $_StatelessLeakingWidget leaks',
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
leakTrackingTestConfig: LeakTrackingTestConfig(
onLeaks: (Leaks theLeaks) {
leaks = theLeaks;
},
failTestOnLeaks: false,
notGCedAllowList: <String, int?>{_leakTrackedClassName: null},
),
);
tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 1, shouldContainDebugInfo: false));
});
group('catches that', () {
// These test cannot run inside other tests because test nesting is forbidden.
// So, `expect` happens outside the tests, in `tearDown`.
late Leaks leaks;
testWidgetsWithLeakTracking(
'$_StatelessLeakingWidget leaks',
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
leakTrackingTestConfig: LeakTrackingTestConfig(
onLeaks: (Leaks theLeaks) {
leaks = theLeaks;
},
failTestOnLeaks: false,
),
);
tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 1, expectedNotGCed: 1, shouldContainDebugInfo: false));
});
},
skip: isBrowser); // [intended] Leak detection is off for web.
testWidgetsWithLeakTracking('Leak tracking is no-op for web', (WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
skip: !isBrowser); // [intended] Leaks detection is off for web.
}
/// Verifies [leaks] contains expected number of leaks for [_LeakTrackedClass].
void _verifyLeaks(
Leaks leaks, {
int expectedNotDisposed = 0,
int expectedNotGCed = 0,
required bool shouldContainDebugInfo,
}) {
const String linkToLeakTracker = 'https://github.com/dart-lang/leak_tracker';
expect(
() => expect(leaks, isLeakFree),
throwsA(
predicate((Object? e) {
return e is TestFailure && e.toString().contains(linkToLeakTracker);
}),
),
);
_verifyLeakList(leaks.notDisposed, expectedNotDisposed, shouldContainDebugInfo);
_verifyLeakList(leaks.notGCed, expectedNotGCed, shouldContainDebugInfo);
}
void _verifyLeakList(List<LeakReport> list, int expectedCount, bool shouldContainDebugInfo){
expect(list.length, expectedCount);
for (final LeakReport leak in list) {
if (shouldContainDebugInfo) {
expect(leak.context, isNotEmpty);
} else {
expect(leak.context ?? <String, dynamic>{}, isEmpty);
}
expect(leak.trackedClass, contains(_LeakTrackedClass.library));
expect(leak.trackedClass, contains(_leakTrackedClassName));
}
}
/// Storage to keep disposed objects, to generate not-gced leaks.
final List<_LeakTrackedClass> _notGcedStorage = <_LeakTrackedClass>[];
class _StatelessLeakingWidget extends StatelessWidget {
_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
Widget build(BuildContext context) {
return const Placeholder();
}
}
class _LeakTrackedClass {
_LeakTrackedClass() {
dispatchObjectCreated(
library: library,
className: '$_LeakTrackedClass',
object: this,
);
}
static const String library = 'package:my_package/lib/src/my_lib.dart';
void dispose() {
dispatchObjectDisposed(object: this);
}
}

View File

@ -5,8 +5,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('debugPrintGestureArenaDiagnostics', (WidgetTester tester) async { testWidgetsWithLeakTracking('debugPrintGestureArenaDiagnostics', (WidgetTester tester) async {

View File

@ -9,8 +9,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
class TestResampleEventFlutterBinding extends AutomatedTestWidgetsFlutterBinding { class TestResampleEventFlutterBinding extends AutomatedTestWidgetsFlutterBinding {
@override @override

View File

@ -6,8 +6,7 @@ import 'dart:ui' as ui;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
class TestResult { class TestResult {
bool dragStarted = false; bool dragStarted = false;

View File

@ -5,8 +5,7 @@
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('kTouchSlop is evaluated in the global coordinate space when scaled up', (WidgetTester tester) async { testWidgetsWithLeakTracking('kTouchSlop is evaluated in the global coordinate space when scaled up', (WidgetTester tester) async {

View File

@ -5,8 +5,7 @@
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async { testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async {

View File

@ -7,12 +7,11 @@ import 'dart:math' as math;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
group('Horizontal', () { group('Horizontal', () {
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async { testWidgets('gets local coordinates', (WidgetTester tester) async {
int dragCancelCount = 0; int dragCancelCount = 0;
final List<DragDownDetails> downDetails = <DragDownDetails>[]; final List<DragDownDetails> downDetails = <DragDownDetails>[];
final List<DragEndDetails> endDetails = <DragEndDetails>[]; final List<DragEndDetails> endDetails = <DragEndDetails>[];

View File

@ -5,10 +5,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async { testWidgets('gets local coordinates', (WidgetTester tester) async {
final List<ScaleStartDetails> startDetails = <ScaleStartDetails>[]; final List<ScaleStartDetails> startDetails = <ScaleStartDetails>[];
final List<ScaleUpdateDetails> updateDetails = <ScaleUpdateDetails>[]; final List<ScaleUpdateDetails> updateDetails = <ScaleUpdateDetails>[];

View File

@ -5,8 +5,7 @@
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async { testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async {

View File

@ -10,8 +10,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
tearDown(() { tearDown(() {
@ -58,7 +57,7 @@ void main() {
expect(find.text('View licenses'), findsOneWidget); expect(find.text('View licenses'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Material2 - AboutListTile control test', (WidgetTester tester) async { testWidgets('Material2 - AboutListTile control test', (WidgetTester tester) async {
const FlutterLogo logo = FlutterLogo(); const FlutterLogo logo = FlutterLogo();
await tester.pumpWidget( await tester.pumpWidget(
@ -141,7 +140,7 @@ void main() {
expect(find.text('Pirate license'), findsOneWidget); expect(find.text('Pirate license'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Material3 - AboutListTile control test', (WidgetTester tester) async { testWidgets('Material3 - AboutListTile control test', (WidgetTester tester) async {
const FlutterLogo logo = FlutterLogo(); const FlutterLogo logo = FlutterLogo();
await tester.pumpWidget( await tester.pumpWidget(
@ -1477,7 +1476,7 @@ void main() {
expect(find.text('Exception: Injected failure'), findsOneWidget); expect(find.text('Exception: Injected failure'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Material2 - LicensePage master view layout position - ltr', (WidgetTester tester) async { testWidgets('Material2 - LicensePage master view layout position - ltr', (WidgetTester tester) async {
const TextDirection textDirection = TextDirection.ltr; const TextDirection textDirection = TextDirection.ltr;
const Size defaultSize = Size(800.0, 600.0); const Size defaultSize = Size(800.0, 600.0);
const Size wideSize = Size(1200.0, 600.0); const Size wideSize = Size(1200.0, 600.0);
@ -1542,7 +1541,7 @@ void main() {
expect(tester.getCenter(find.byType(ListView)), const Offset(160, 356)); expect(tester.getCenter(find.byType(ListView)), const Offset(160, 356));
}); });
testWidgetsWithLeakTracking('Material3 - LicensePage master view layout position - ltr', (WidgetTester tester) async { testWidgets('Material3 - LicensePage master view layout position - ltr', (WidgetTester tester) async {
const TextDirection textDirection = TextDirection.ltr; const TextDirection textDirection = TextDirection.ltr;
const Size defaultSize = Size(800.0, 600.0); const Size defaultSize = Size(800.0, 600.0);
const Size wideSize = Size(1200.0, 600.0); const Size wideSize = Size(1200.0, 600.0);
@ -1609,7 +1608,7 @@ void main() {
expect(tester.getCenter(find.byType(ListView)), const Offset(160, 356)); expect(tester.getCenter(find.byType(ListView)), const Offset(160, 356));
}); });
testWidgetsWithLeakTracking('Material2 - LicensePage master view layout position - rtl', (WidgetTester tester) async { testWidgets('Material2 - LicensePage master view layout position - rtl', (WidgetTester tester) async {
const TextDirection textDirection = TextDirection.rtl; const TextDirection textDirection = TextDirection.rtl;
const Size defaultSize = Size(800.0, 600.0); const Size defaultSize = Size(800.0, 600.0);
const Size wideSize = Size(1200.0, 600.0); const Size wideSize = Size(1200.0, 600.0);
@ -1674,7 +1673,7 @@ void main() {
expect(tester.getCenter(find.byType(ListView)), const Offset(1040.0, 356.0)); expect(tester.getCenter(find.byType(ListView)), const Offset(1040.0, 356.0));
}); });
testWidgetsWithLeakTracking('Material3 - LicensePage master view layout position - rtl', (WidgetTester tester) async { testWidgets('Material3 - LicensePage master view layout position - rtl', (WidgetTester tester) async {
const TextDirection textDirection = TextDirection.rtl; const TextDirection textDirection = TextDirection.rtl;
const Size defaultSize = Size(800.0, 600.0); const Size defaultSize = Size(800.0, 600.0);
const Size wideSize = Size(1200.0, 600.0); const Size wideSize = Size(1200.0, 600.0);
@ -1741,7 +1740,7 @@ void main() {
expect(tester.getCenter(find.byType(ListView)), const Offset(1040.0, 356.0)); expect(tester.getCenter(find.byType(ListView)), const Offset(1040.0, 356.0));
}); });
testWidgetsWithLeakTracking('License page title in lateral UI does not use AppBarTheme.foregroundColor', (WidgetTester tester) async { testWidgets('License page title in lateral UI does not use AppBarTheme.foregroundColor', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/108991 // This is a regression test for https://github.com/flutter/flutter/issues/108991
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
appBarTheme: const AppBarTheme(foregroundColor: Color(0xFFFFFFFF)), appBarTheme: const AppBarTheme(foregroundColor: Color(0xFFFFFFFF)),

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
/// Adds the basic requirements for a Chip. /// Adds the basic requirements for a Chip.
Widget wrapForChip({ Widget wrapForChip({

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('ActionIconThemeData copyWith, ==, hashCode basics', () { test('ActionIconThemeData copyWith, ==, hashCode basics', () {

View File

@ -7,8 +7,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/clipboard_utils.dart'; import '../widgets/clipboard_utils.dart';
import '../widgets/editable_text_utils.dart'; import '../widgets/editable_text_utils.dart';
import '../widgets/live_text_utils.dart'; import '../widgets/live_text_utils.dart';
@ -112,7 +111,7 @@ void main() {
expect(find.byKey(key), findsOneWidget); expect(find.byKey(key), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Can build from EditableTextState', (WidgetTester tester) async { testWidgets('Can build from EditableTextState', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
@ -233,7 +232,7 @@ void main() {
); );
group('buttonItems', () { group('buttonItems', () {
testWidgetsWithLeakTracking('getEditableTextButtonItems builds the correct button items per-platform', (WidgetTester tester) async { testWidgets('getEditableTextButtonItems builds the correct button items per-platform', (WidgetTester tester) async {
// Fill the clipboard so that the Paste option is available in the text // Fill the clipboard so that the Paste option is available in the text
// selection menu. // selection menu.
await Clipboard.setData(const ClipboardData(text: 'Clipboard data')); await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
@ -328,7 +327,7 @@ void main() {
skip: kIsWeb, // [intended] skip: kIsWeb, // [intended]
); );
testWidgetsWithLeakTracking('getAdaptiveButtons builds the correct button widgets per-platform', (WidgetTester tester) async { testWidgets('getAdaptiveButtons builds the correct button widgets per-platform', (WidgetTester tester) async {
const String buttonText = 'Click me'; const String buttonText = 'Click me';
await tester.pumpWidget( await tester.pumpWidget(

View File

@ -9,8 +9,7 @@ import 'dart:math' as math show pi;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
class MockCanvas extends Fake implements Canvas { class MockCanvas extends Fake implements Canvas {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking("builder doesn't get called if app doesn't change", (WidgetTester tester) async { testWidgetsWithLeakTracking("builder doesn't get called if app doesn't change", (WidgetTester tester) async {

View File

@ -5,8 +5,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgets('BackButton control test', (WidgetTester tester) async { testWidgets('BackButton control test', (WidgetTester tester) async {

View File

@ -6,8 +6,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('BadgeThemeData copyWith, ==, hashCode basics', () { test('BadgeThemeData copyWith, ==, hashCode basics', () {

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('MaterialBanner properties are respected', (WidgetTester tester) async { testWidgetsWithLeakTracking('MaterialBanner properties are respected', (WidgetTester tester) async {

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('MaterialBannerThemeData copyWith, ==, hashCode basics', () { test('MaterialBannerThemeData copyWith, ==, hashCode basics', () {

View File

@ -10,8 +10,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('Material3 - Shadow effect is not doubled', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material3 - Shadow effect is not doubled', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/123064 // Regression test for https://github.com/flutter/flutter/issues/123064

View File

@ -9,8 +9,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('BottomAppBarTheme lerp special cases', () { test('BottomAppBarTheme lerp special cases', () {

View File

@ -12,9 +12,9 @@ import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'package:vector_math/vector_math_64.dart' show Vector3; import 'package:vector_math/vector_math_64.dart' show Vector3;
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';

View File

@ -6,10 +6,9 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'package:vector_math/vector_math_64.dart' show Vector3; import 'package:vector_math/vector_math_64.dart' show Vector3;
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('BottomNavigationBarThemeData copyWith, ==, hashCode basics', () { test('BottomNavigationBarThemeData copyWith, ==, hashCode basics', () {

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('BottomSheetThemeData copyWith, ==, hashCode basics', () { test('BottomSheetThemeData copyWith, ==, hashCode basics', () {
@ -171,7 +170,7 @@ void main() {
expect(material.clipBehavior, clipBehavior); expect(material.clipBehavior, clipBehavior);
}); });
testWidgetsWithLeakTracking('Modal bottom sheet-specific parameters are used for modal bottom sheets', (WidgetTester tester) async { testWidgets('Modal bottom sheet-specific parameters are used for modal bottom sheets', (WidgetTester tester) async {
const double modalElevation = 5.0; const double modalElevation = 5.0;
const double persistentElevation = 7.0; const double persistentElevation = 7.0;
const Color modalBackgroundColor = Colors.yellow; const Color modalBackgroundColor = Colors.yellow;
@ -250,7 +249,7 @@ void main() {
expect(material.color, null); expect(material.color, null);
}); });
testWidgetsWithLeakTracking('Modal bottom sheets respond to theme changes', (WidgetTester tester) async { testWidgets('Modal bottom sheets respond to theme changes', (WidgetTester tester) async {
const double lightElevation = 5.0; const double lightElevation = 5.0;
const double darkElevation = 3.0; const double darkElevation = 3.0;
const Color lightBackgroundColor = Colors.green; const Color lightBackgroundColor = Colors.green;

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('ButtonBar default control smoketest', (WidgetTester tester) async { testWidgetsWithLeakTracking('ButtonBar default control smoketest', (WidgetTester tester) async {
@ -341,7 +340,7 @@ void main() {
group('layoutBehavior', () { group('layoutBehavior', () {
testWidgetsWithLeakTracking('ButtonBar has a min height of 52 when using ButtonBarLayoutBehavior.constrained', (WidgetTester tester) async { testWidgets('ButtonBar has a min height of 52 when using ButtonBarLayoutBehavior.constrained', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const SingleChildScrollView( const SingleChildScrollView(
child: ListBody( child: ListBody(
@ -364,7 +363,7 @@ void main() {
expect(tester.getBottomRight(buttonBar).dy - tester.getTopRight(buttonBar).dy, 52.0); expect(tester.getBottomRight(buttonBar).dy - tester.getTopRight(buttonBar).dy, 52.0);
}); });
testWidgetsWithLeakTracking('ButtonBar has padding applied when using ButtonBarLayoutBehavior.padded', (WidgetTester tester) async { testWidgets('ButtonBar has padding applied when using ButtonBarLayoutBehavior.padded', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const SingleChildScrollView( const SingleChildScrollView(
child: ListBody( child: ListBody(

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {

View File

@ -6,8 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('ButtonStyle copyWith, merge, ==, hashCode basics', () { test('ButtonStyle copyWith, merge, ==, hashCode basics', () {

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {

View File

@ -8,8 +8,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
Widget wrap({ required Widget child }) { Widget wrap({ required Widget child }) {
@ -496,6 +495,8 @@ void main() {
await tester.pump(); await tester.pump();
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('CheckboxListTile can be disabled', (WidgetTester tester) async { testWidgetsWithLeakTracking('CheckboxListTile can be disabled', (WidgetTester tester) async {

View File

@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('CheckboxThemeData copyWith, ==, hashCode basics', () { test('CheckboxThemeData copyWith, ==, hashCode basics', () {
@ -302,7 +301,7 @@ void main() {
expect(_getCheckboxMaterial(tester), paints..path(color: selectedFillColor)); expect(_getCheckboxMaterial(tester), paints..path(color: selectedFillColor));
}); });
testWidgetsWithLeakTracking('Checkbox theme overlay color resolves in active/pressed states', (WidgetTester tester) async { testWidgets('Checkbox theme overlay color resolves in active/pressed states', (WidgetTester tester) async {
const Color activePressedOverlayColor = Color(0xFF000001); const Color activePressedOverlayColor = Color(0xFF000001);
const Color inactivePressedOverlayColor = Color(0xFF000002); const Color inactivePressedOverlayColor = Color(0xFF000002);

View File

@ -7,8 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
@ -701,7 +700,7 @@ void main() {
expect(calledDelete, isFalse); expect(calledDelete, isFalse);
}); });
testWidgetsWithLeakTracking('Chip elements are ordered horizontally for locale', (WidgetTester tester) async { testWidgets('Chip elements are ordered horizontally for locale', (WidgetTester tester) async {
final UniqueKey iconKey = UniqueKey(); final UniqueKey iconKey = UniqueKey();
final Widget test = Overlay( final Widget test = Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
@ -877,7 +876,7 @@ void main() {
expect(tester.getSize(find.byKey(keyA)), equals(const Size(20.0, 20.0))); expect(tester.getSize(find.byKey(keyA)), equals(const Size(20.0, 20.0)));
}); });
testWidgetsWithLeakTracking('Chip padding - LTR', (WidgetTester tester) async { testWidgets('Chip padding - LTR', (WidgetTester tester) async {
final GlobalKey keyA = GlobalKey(); final GlobalKey keyA = GlobalKey();
final GlobalKey keyB = GlobalKey(); final GlobalKey keyB = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
@ -913,7 +912,7 @@ void main() {
expect(tester.getBottomRight(find.byType(Icon)), const Offset(457.0, 309.0)); expect(tester.getBottomRight(find.byType(Icon)), const Offset(457.0, 309.0));
}); });
testWidgetsWithLeakTracking('Chip padding - RTL', (WidgetTester tester) async { testWidgets('Chip padding - RTL', (WidgetTester tester) async {
final GlobalKey keyA = GlobalKey(); final GlobalKey keyA = GlobalKey();
final GlobalKey keyB = GlobalKey(); final GlobalKey keyB = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
@ -2633,7 +2632,7 @@ void main() {
expect(find.byType(InkWell), findsOneWidget); expect(find.byType(InkWell), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Chip uses stateful color for text color in different states', (WidgetTester tester) async { testWidgets('Chip uses stateful color for text color in different states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
const Color pressedColor = Color(0x00000001); const Color pressedColor = Color(0x00000001);
@ -2721,7 +2720,7 @@ void main() {
expect(textColor(), disabledColor); expect(textColor(), disabledColor);
}); });
testWidgetsWithLeakTracking('Chip uses stateful border side color in different states', (WidgetTester tester) async { testWidgets('Chip uses stateful border side color in different states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
const Color pressedColor = Color(0x00000001); const Color pressedColor = Color(0x00000001);
@ -2801,7 +2800,7 @@ void main() {
expect(find.byType(RawChip), paints..rrect()..rrect(color: disabledColor)); expect(find.byType(RawChip), paints..rrect()..rrect(color: disabledColor));
}); });
testWidgetsWithLeakTracking('Chip uses stateful border side color from resolveWith', (WidgetTester tester) async { testWidgets('Chip uses stateful border side color from resolveWith', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
const Color pressedColor = Color(0x00000001); const Color pressedColor = Color(0x00000001);
@ -2882,7 +2881,7 @@ void main() {
}); });
testWidgetsWithLeakTracking('Chip uses stateful nullable border side color from resolveWith', (WidgetTester tester) async { testWidgets('Chip uses stateful nullable border side color from resolveWith', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
const Color pressedColor = Color(0x00000001); const Color pressedColor = Color(0x00000001);
@ -2971,7 +2970,7 @@ void main() {
expect(find.byType(RawChip), paints..rrect()..rrect(color: disabledColor)); expect(find.byType(RawChip), paints..rrect()..rrect(color: disabledColor));
}); });
testWidgetsWithLeakTracking('Chip uses stateful shape in different states', (WidgetTester tester) async { testWidgets('Chip uses stateful shape in different states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
OutlinedBorder? getShape(Set<MaterialState> states) { OutlinedBorder? getShape(Set<MaterialState> states) {
@ -3339,7 +3338,7 @@ void main() {
expect(decoration.shape, shape); expect(decoration.shape, shape);
}); });
testWidgetsWithLeakTracking('Chip highlight color is drawn on top of the backgroundColor', (WidgetTester tester) async { testWidgets('Chip highlight color is drawn on top of the backgroundColor', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'RawChip'); final FocusNode focusNode = FocusNode(debugLabel: 'RawChip');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color backgroundColor = Color(0xff00ff00); const Color backgroundColor = Color(0xff00ff00);

View File

@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
RenderBox getMaterialBox(WidgetTester tester) { RenderBox getMaterialBox(WidgetTester tester) {
return tester.firstRenderObject<RenderBox>( return tester.firstRenderObject<RenderBox>(
@ -641,6 +640,8 @@ void main() {
await tester.pumpWidget(chipWidget(enabled: false)); await tester.pumpWidget(chipWidget(enabled: false));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(textColor(), disabledColor); expect(textColor(), disabledColor);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Chip uses stateful border side from resolveWith pattern', (WidgetTester tester) async { testWidgetsWithLeakTracking('Chip uses stateful border side from resolveWith pattern', (WidgetTester tester) async {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
RenderBox getMaterialBox(WidgetTester tester, Finder type) { RenderBox getMaterialBox(WidgetTester tester, Finder type) {
return tester.firstRenderObject<RenderBox>( return tester.firstRenderObject<RenderBox>(

View File

@ -12,8 +12,7 @@ import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../image_data.dart'; import '../image_data.dart';
import '../painting/mocks_for_image_cache.dart'; import '../painting/mocks_for_image_cache.dart';

View File

@ -11,9 +11,9 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'package:vector_math/vector_math_64.dart' show Matrix3; import 'package:vector_math/vector_math_64.dart' show Matrix3;
import '../foundation/leak_tracking.dart';
import 'data_table_test_utils.dart'; import 'data_table_test_utils.dart';
void main() { void main() {

View File

@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('DataTableThemeData copyWith, ==, hashCode basics', () { test('DataTableThemeData copyWith, ==, hashCode basics', () {

View File

@ -8,8 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
void main() { void main() {
@ -260,6 +259,7 @@ void main() {
// https://github.com/flutter/flutter/issues/130354 // https://github.com/flutter/flutter/issues/130354
leakTrackingTestConfig: const LeakTrackingTestConfig( leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotGCed: true, allowAllNotGCed: true,
allowAllNotDisposed: true,
)); ));
}); });

View File

@ -5,8 +5,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('debugCheckHasMaterial control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('debugCheckHasMaterial control test', (WidgetTester tester) async {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();

View File

@ -9,8 +9,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
MaterialApp _buildAppWithDialog( MaterialApp _buildAppWithDialog(
@ -2338,7 +2337,7 @@ void main() {
}); });
group('AlertDialog.scrollable: ', () { group('AlertDialog.scrollable: ', () {
testWidgetsWithLeakTracking('Title is scrollable', (WidgetTester tester) async { testWidgets('Title is scrollable', (WidgetTester tester) async {
final Key titleKey = UniqueKey(); final Key titleKey = UniqueKey();
final AlertDialog dialog = AlertDialog( final AlertDialog dialog = AlertDialog(
title: Container( title: Container(
@ -2378,7 +2377,7 @@ void main() {
expect(box.localToGlobal(Offset.zero), equals(originalOffset.translate(0.0, -200.0))); expect(box.localToGlobal(Offset.zero), equals(originalOffset.translate(0.0, -200.0)));
}); });
testWidgetsWithLeakTracking('Title and content are scrollable', (WidgetTester tester) async { testWidgets('Title and content are scrollable', (WidgetTester tester) async {
final Key titleKey = UniqueKey(); final Key titleKey = UniqueKey();
final Key contentKey = UniqueKey(); final Key contentKey = UniqueKey();
final AlertDialog dialog = AlertDialog( final AlertDialog dialog = AlertDialog(
@ -2511,7 +2510,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgetsWithLeakTracking('DialogRoute is state restorable', (WidgetTester tester) async { testWidgets('DialogRoute is state restorable', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
restorationScopeId: 'app', restorationScopeId: 'app',
@ -2660,6 +2659,9 @@ void main() {
expect(await previousFocus(), true); expect(await previousFocus(), true);
expect(okNode.hasFocus, true); expect(okNode.hasFocus, true);
expect(cancelNode.hasFocus, false); expect(cancelNode.hasFocus, false);
cancelNode.dispose();
okNode.dispose();
}); });
testWidgets('Adaptive AlertDialog shows correct widget on each platform', (WidgetTester tester) async { testWidgets('Adaptive AlertDialog shows correct widget on each platform', (WidgetTester tester) async {
@ -2764,7 +2766,7 @@ void main() {
expect(find.text('Dialog2'), findsOneWidget); expect(find.text('Dialog2'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Uses open focus traversal when overridden', (WidgetTester tester) async { testWidgets('Uses open focus traversal when overridden', (WidgetTester tester) async {
final FocusNode okNode = FocusNode(); final FocusNode okNode = FocusNode();
final FocusNode cancelNode = FocusNode(); final FocusNode cancelNode = FocusNode();

View File

@ -5,11 +5,10 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('DrawerButton control test', (WidgetTester tester) async { testWidgets('DrawerButton control test', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
home: Scaffold( home: Scaffold(
@ -171,7 +170,7 @@ void main() {
handle.dispose(); handle.dispose();
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
testWidgetsWithLeakTracking('EndDrawerButton control test', (WidgetTester tester) async { testWidgets('EndDrawerButton control test', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
home: Scaffold( home: Scaffold(

View File

@ -8,8 +8,6 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
const List<String> menuItems = <String>['one', 'two', 'three', 'four']; const List<String> menuItems = <String>['one', 'two', 'three', 'four'];
void onChanged<T>(T _) { } void onChanged<T>(T _) { }
final Type dropdownButtonType = DropdownButton<String>( final Type dropdownButtonType = DropdownButton<String>(
@ -201,7 +199,7 @@ void main() {
expect(hintEmptyLabel, oneValueLabel); expect(hintEmptyLabel, oneValueLabel);
}); });
testWidgetsWithLeakTracking('label position test - show disabledHint: disable', (WidgetTester tester) async { testWidgets('label position test - show disabledHint: disable', (WidgetTester tester) async {
int? value; int? value;
await tester.pumpWidget( await tester.pumpWidget(
@ -239,7 +237,7 @@ void main() {
expect(hintEmptyLabel, const Offset(0.0, 12.0)); expect(hintEmptyLabel, const Offset(0.0, 12.0));
}); });
testWidgetsWithLeakTracking('label position test - show disabledHint: enable + null item', (WidgetTester tester) async { testWidgets('label position test - show disabledHint: enable + null item', (WidgetTester tester) async {
int? value; int? value;
await tester.pumpWidget( await tester.pumpWidget(
@ -264,7 +262,7 @@ void main() {
expect(hintEmptyLabel, const Offset(0.0, 12.0)); expect(hintEmptyLabel, const Offset(0.0, 12.0));
}); });
testWidgetsWithLeakTracking('label position test - show disabledHint: enable + empty item', (WidgetTester tester) async { testWidgets('label position test - show disabledHint: enable + empty item', (WidgetTester tester) async {
int? value; int? value;
await tester.pumpWidget( await tester.pumpWidget(
@ -314,7 +312,7 @@ void main() {
expect(hintEmptyLabel, const Offset(0.0, 12.0)); expect(hintEmptyLabel, const Offset(0.0, 12.0));
}); });
testWidgetsWithLeakTracking('label position test - no hint shown: enable + no selected + disabledHint', (WidgetTester tester) async { testWidgets('label position test - no hint shown: enable + no selected + disabledHint', (WidgetTester tester) async {
int? value; int? value;
await tester.pumpWidget( await tester.pumpWidget(
@ -352,7 +350,7 @@ void main() {
expect(hintEmptyLabel, const Offset(0.0, 24.0)); expect(hintEmptyLabel, const Offset(0.0, 24.0));
}); });
testWidgetsWithLeakTracking('label position test - show selected item: disabled + hint + disabledHint', (WidgetTester tester) async { testWidgets('label position test - show selected item: disabled + hint + disabledHint', (WidgetTester tester) async {
const int value = 1; const int value = 1;
await tester.pumpWidget( await tester.pumpWidget(
@ -392,7 +390,7 @@ void main() {
}); });
// Regression test for https://github.com/flutter/flutter/issues/82910 // Regression test for https://github.com/flutter/flutter/issues/82910
testWidgetsWithLeakTracking('null value test', (WidgetTester tester) async { testWidgets('null value test', (WidgetTester tester) async {
int? value = 1; int? value = 1;
await tester.pumpWidget( await tester.pumpWidget(
@ -493,7 +491,7 @@ void main() {
expect(value, equals('three')); expect(value, equals('three'));
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField arrow icon aligns with the edge of button when expanded', (WidgetTester tester) async { testWidgets('DropdownButtonFormField arrow icon aligns with the edge of button when expanded', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
// There shouldn't be overflow when expanded although list contains longer items. // There shouldn't be overflow when expanded although list contains longer items.
@ -528,7 +526,7 @@ void main() {
); );
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField with isDense:true aligns selected menu item', (WidgetTester tester) async { testWidgets('DropdownButtonFormField with isDense:true aligns selected menu item', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
@ -568,7 +566,7 @@ void main() {
} }
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField with isDense:true does not clip large scale text', testWidgets('DropdownButtonFormField with isDense:true does not clip large scale text',
(WidgetTester tester) async { (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
const String value = 'two'; const String value = 'two';
@ -607,7 +605,7 @@ void main() {
expect(box.size.height, 72.0); expect(box.size.height, 72.0);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField.isDense is true by default', (WidgetTester tester) async { testWidgets('DropdownButtonFormField.isDense is true by default', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/46844 // Regression test for https://github.com/flutter/flutter/issues/46844
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
const String value = 'two'; const String value = 'two';
@ -638,7 +636,7 @@ void main() {
expect(box.size.height, 48.0); expect(box.size.height, 48.0);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - custom text style', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - custom text style', (WidgetTester tester) async {
const String value = 'foo'; const String value = 'foo';
final UniqueKey itemKey = UniqueKey(); final UniqueKey itemKey = UniqueKey();
@ -676,7 +674,7 @@ void main() {
expect(richText.text.style!.fontSize, 20.0); expect(richText.text.style!.fontSize, 20.0);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - disabledHint displays when the items list is empty, when items is null', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - disabledHint displays when the items list is empty, when items is null', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
Widget build({ List<String>? items }) { Widget build({ List<String>? items }) {
@ -699,7 +697,7 @@ void main() {
expect(find.text('disabled'), findsOneWidget); expect(find.text('disabled'), findsOneWidget);
}); });
testWidgetsWithLeakTracking( testWidgets(
'DropdownButtonFormField - hint displays when the items list is ' 'DropdownButtonFormField - hint displays when the items list is '
'empty, items is null, and disabledHint is null', 'empty, items is null, and disabledHint is null',
(WidgetTester tester) async { (WidgetTester tester) async {
@ -723,7 +721,7 @@ void main() {
}, },
); );
testWidgetsWithLeakTracking('DropdownButtonFormField - disabledHint is null by default', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - disabledHint is null by default', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
Widget build({ List<String>? items }) { Widget build({ List<String>? items }) {
@ -743,7 +741,7 @@ void main() {
expect(find.text('hint used when disabled'), findsOneWidget); expect(find.text('hint used when disabled'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - disabledHint is null by default', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - disabledHint is null by default', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
Widget build({ List<String>? items }) { Widget build({ List<String>? items }) {
@ -763,7 +761,7 @@ void main() {
expect(find.text('hint used when disabled'), findsOneWidget); expect(find.text('hint used when disabled'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - disabledHint displays when onChanged is null', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - disabledHint displays when onChanged is null', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
Widget build({ List<String>? items, ValueChanged<String?>? onChanged }) { Widget build({ List<String>? items, ValueChanged<String?>? onChanged }) {
@ -781,7 +779,7 @@ void main() {
expect(find.text('disabled'), findsOneWidget); expect(find.text('disabled'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - disabled hint should be of same size as enabled hint', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - disabled hint should be of same size as enabled hint', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
Widget build({ List<String>? items}) { Widget build({ List<String>? items}) {
@ -806,7 +804,7 @@ void main() {
expect(enabledHintBox.size, equals(disabledHintBox.size)); expect(enabledHintBox.size, equals(disabledHintBox.size));
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - Custom icon size and colors', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - Custom icon size and colors', (WidgetTester tester) async {
final Key iconKey = UniqueKey(); final Key iconKey = UniqueKey();
final Icon customIcon = Icon(Icons.assessment, key: iconKey); final Icon customIcon = Icon(Icons.assessment, key: iconKey);
@ -839,7 +837,7 @@ void main() {
expect(disabledRichText.text.style!.color, Colors.orange); expect(disabledRichText.text.style!.color, Colors.orange);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - default elevation', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - default elevation', (WidgetTester tester) async {
final Key buttonKey = UniqueKey(); final Key buttonKey = UniqueKey();
debugDisableShadows = false; debugDisableShadows = false;
await tester.pumpWidget(buildFormFrame( await tester.pumpWidget(buildFormFrame(
@ -896,7 +894,7 @@ void main() {
debugDisableShadows = true; debugDisableShadows = true;
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField does not allow duplicate item values', (WidgetTester tester) async { testWidgets('DropdownButtonFormField does not allow duplicate item values', (WidgetTester tester) async {
final List<DropdownMenuItem<String>> itemsWithDuplicateValues = <String>['a', 'b', 'c', 'c'] final List<DropdownMenuItem<String>> itemsWithDuplicateValues = <String>['a', 'b', 'c', 'c']
.map<DropdownMenuItem<String>>((String value) { .map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
@ -925,7 +923,7 @@ void main() {
); );
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField value should only appear in one menu item', (WidgetTester tester) async { testWidgets('DropdownButtonFormField value should only appear in one menu item', (WidgetTester tester) async {
final List<DropdownMenuItem<String>> itemsWithDuplicateValues = <String>['a', 'b', 'c', 'd'] final List<DropdownMenuItem<String>> itemsWithDuplicateValues = <String>['a', 'b', 'c', 'd']
.map<DropdownMenuItem<String>>((String value) { .map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
@ -1090,7 +1088,7 @@ void main() {
expect(find.text(currentValue), findsOneWidget); expect(find.text(currentValue), findsOneWidget);
}); });
testWidgetsWithLeakTracking('autovalidateMode is passed to super', (WidgetTester tester) async { testWidgets('autovalidateMode is passed to super', (WidgetTester tester) async {
int validateCalled = 0; int validateCalled = 0;
await tester.pumpWidget( await tester.pumpWidget(
@ -1119,7 +1117,7 @@ void main() {
expect(validateCalled, 1); expect(validateCalled, 1);
}); });
testWidgetsWithLeakTracking('DropdownButtonFormField - Custom button alignment', (WidgetTester tester) async { testWidgets('DropdownButtonFormField - Custom button alignment', (WidgetTester tester) async {
await tester.pumpWidget(buildFormFrame( await tester.pumpWidget(buildFormFrame(
buttonAlignment: AlignmentDirectional.center, buttonAlignment: AlignmentDirectional.center,
items: <String>['one'], items: <String>['one'],

View File

@ -5,8 +5,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('DropdownMenuThemeData copyWith, ==, hashCode basics', () { test('DropdownMenuThemeData copyWith, ==, hashCode basics', () {
@ -44,7 +43,7 @@ void main() {
expect(description, <String>[]); expect(description, <String>[]);
}); });
testWidgetsWithLeakTracking('With no other configuration, defaults are used', (WidgetTester tester) async { testWidgets('With no other configuration, defaults are used', (WidgetTester tester) async {
final ThemeData themeData = ThemeData(); final ThemeData themeData = ThemeData();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
@ -101,7 +100,7 @@ void main() {
expect(material.textStyle?.color, themeData.colorScheme.onSurface); expect(material.textStyle?.color, themeData.colorScheme.onSurface);
}); });
testWidgetsWithLeakTracking('ThemeData.dropdownMenuTheme overrides defaults', (WidgetTester tester) async { testWidgets('ThemeData.dropdownMenuTheme overrides defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
dropdownMenuTheme: DropdownMenuThemeData( dropdownMenuTheme: DropdownMenuThemeData(
textStyle: TextStyle( textStyle: TextStyle(
@ -180,7 +179,7 @@ void main() {
expect(material.textStyle?.color, theme.colorScheme.onSurface); expect(material.textStyle?.color, theme.colorScheme.onSurface);
}); });
testWidgetsWithLeakTracking('DropdownMenuTheme overrides ThemeData and defaults', (WidgetTester tester) async { testWidgets('DropdownMenuTheme overrides ThemeData and defaults', (WidgetTester tester) async {
final DropdownMenuThemeData global = DropdownMenuThemeData( final DropdownMenuThemeData global = DropdownMenuThemeData(
textStyle: TextStyle( textStyle: TextStyle(
color: Colors.orange, color: Colors.orange,
@ -283,7 +282,7 @@ void main() {
expect(material.textStyle?.color, theme.colorScheme.onSurface); expect(material.textStyle?.color, theme.colorScheme.onSurface);
}); });
testWidgetsWithLeakTracking('Widget parameters overrides DropdownMenuTheme, ThemeData and defaults', (WidgetTester tester) async { testWidgets('Widget parameters overrides DropdownMenuTheme, ThemeData and defaults', (WidgetTester tester) async {
final DropdownMenuThemeData global = DropdownMenuThemeData( final DropdownMenuThemeData global = DropdownMenuThemeData(
textStyle: TextStyle( textStyle: TextStyle(
color: Colors.orange, color: Colors.orange,

View File

@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {
@ -196,6 +195,7 @@ void main() {
await gesture.moveTo(center); await gesture.moveTo(center);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await expectLater(tester, meetsGuideline(textContrastGuideline)); await expectLater(tester, meetsGuideline(textContrastGuideline));
focusNode.dispose();
}, },
skip: isBrowser, // https://github.com/flutter/flutter/issues/44115 skip: isBrowser, // https://github.com/flutter/flutter/issues/44115
); );
@ -259,6 +259,8 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(elevation(), 1.0); expect(elevation(), 1.0);
expect(overlayColor(), paints..rect(color: theme.colorScheme.primary.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.primary.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ElevatedButton uses stateful color for text color in different states', (WidgetTester tester) async { testWidgetsWithLeakTracking('ElevatedButton uses stateful color for text color in different states', (WidgetTester tester) async {
@ -334,6 +336,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(textColor(), pressedColor); expect(textColor(), pressedColor);
focusNode.dispose();
}); });
@ -410,6 +414,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(iconColor(), pressedColor); expect(iconColor(), pressedColor);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ElevatedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async { testWidgetsWithLeakTracking('ElevatedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
@ -534,6 +540,8 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('disabled and hovered ElevatedButton responds to mouse-exit', (WidgetTester tester) async { testWidgetsWithLeakTracking('disabled and hovered ElevatedButton responds to mouse-exit', (WidgetTester tester) async {
@ -625,6 +633,8 @@ void main() {
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('When ElevatedButton disable, Can not set ElevatedButton focus.', (WidgetTester tester) async { testWidgetsWithLeakTracking('When ElevatedButton disable, Can not set ElevatedButton focus.', (WidgetTester tester) async {
@ -648,6 +658,9 @@ void main() {
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('Does ElevatedButton work with hover', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does ElevatedButton work with hover', (WidgetTester tester) async {
@ -703,6 +716,8 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does ElevatedButton work with autofocus', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does ElevatedButton work with autofocus', (WidgetTester tester) async {
@ -733,6 +748,8 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does ElevatedButton contribute semantics', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does ElevatedButton contribute semantics', (WidgetTester tester) async {
@ -1667,7 +1684,7 @@ void main() {
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
}); });
testWidgetsWithLeakTracking('ElevatedButton in SelectionArea changes mouse cursor when hovered', (WidgetTester tester) async { testWidgets('ElevatedButton in SelectionArea changes mouse cursor when hovered', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/104595. // Regression test for https://github.com/flutter/flutter/issues/104595.
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: SelectionArea( home: SelectionArea(
@ -1865,15 +1882,15 @@ void main() {
await gesture.removePointer(); await gesture.removePointer();
} }
testWidgetsWithLeakTracking('ElevatedButton statesController', (WidgetTester tester) async { testWidgets('ElevatedButton statesController', (WidgetTester tester) async {
testStatesController(null, tester); testStatesController(null, tester);
}); });
testWidgetsWithLeakTracking('ElevatedButton.icon statesController', (WidgetTester tester) async { testWidgets('ElevatedButton.icon statesController', (WidgetTester tester) async {
testStatesController(const Icon(Icons.add), tester); testStatesController(const Icon(Icons.add), tester);
}); });
testWidgetsWithLeakTracking('Disabled ElevatedButton statesController', (WidgetTester tester) async { testWidgets('Disabled ElevatedButton statesController', (WidgetTester tester) async {
int count = 0; int count = 0;
void valueChanged() { void valueChanged() {
count += 1; count += 1;

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('ElevatedButtonThemeData lerp special cases', () { test('ElevatedButtonThemeData lerp special cases', () {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
Widget wrap({ required Widget child, ThemeData? theme }) { Widget wrap({ required Widget child, ThemeData? theme }) {
return MaterialApp( return MaterialApp(

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
class SimpleExpansionPanelListTestWidget extends StatefulWidget { class SimpleExpansionPanelListTestWidget extends StatefulWidget {
const SimpleExpansionPanelListTestWidget({ const SimpleExpansionPanelListTestWidget({

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
class TestIcon extends StatefulWidget { class TestIcon extends StatefulWidget {
const TestIcon({super.key}); const TestIcon({super.key});

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
class TestIcon extends StatefulWidget { class TestIcon extends StatefulWidget {
const TestIcon({super.key}); const TestIcon({super.key});

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';

View File

@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {
@ -340,6 +339,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(elevation(), 0.0); expect(elevation(), 0.0);
expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('FilledButton.tonal default overlayColor and elevation resolve pressed state', (WidgetTester tester) async { testWidgetsWithLeakTracking('FilledButton.tonal default overlayColor and elevation resolve pressed state', (WidgetTester tester) async {
@ -405,6 +405,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(elevation(), 0.0); expect(elevation(), 0.0);
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('FilledButton uses stateful color for text color in different states', (WidgetTester tester) async { testWidgetsWithLeakTracking('FilledButton uses stateful color for text color in different states', (WidgetTester tester) async {
@ -480,6 +481,7 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(textColor(), pressedColor); expect(textColor(), pressedColor);
focusNode.dispose();
}); });
@ -556,6 +558,7 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(iconColor(), pressedColor); expect(iconColor(), pressedColor);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('FilledButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async { testWidgetsWithLeakTracking('FilledButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
@ -680,6 +683,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('disabled and hovered FilledButton responds to mouse-exit', (WidgetTester tester) async { testWidgetsWithLeakTracking('disabled and hovered FilledButton responds to mouse-exit', (WidgetTester tester) async {
@ -771,6 +775,7 @@ void main() {
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('When FilledButton disable, Can not set FilledButton focus.', (WidgetTester tester) async { testWidgetsWithLeakTracking('When FilledButton disable, Can not set FilledButton focus.', (WidgetTester tester) async {
@ -794,6 +799,7 @@ void main() {
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('Does FilledButton work with hover', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does FilledButton work with hover', (WidgetTester tester) async {
@ -849,6 +855,7 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does FilledButton work with autofocus', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does FilledButton work with autofocus', (WidgetTester tester) async {
@ -879,6 +886,7 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does FilledButton contribute semantics', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does FilledButton contribute semantics', (WidgetTester tester) async {
@ -1741,7 +1749,7 @@ void main() {
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
}); });
testWidgetsWithLeakTracking('FilledButton in SelectionArea changes mouse cursor when hovered', (WidgetTester tester) async { testWidgets('FilledButton in SelectionArea changes mouse cursor when hovered', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/104595. // Regression test for https://github.com/flutter/flutter/issues/104595.
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: SelectionArea( home: SelectionArea(
@ -1937,15 +1945,15 @@ void main() {
await gesture.removePointer(); await gesture.removePointer();
} }
testWidgetsWithLeakTracking('FilledButton statesController', (WidgetTester tester) async { testWidgets('FilledButton statesController', (WidgetTester tester) async {
testStatesController(null, tester); testStatesController(null, tester);
}); });
testWidgetsWithLeakTracking('FilledButton.icon statesController', (WidgetTester tester) async { testWidgets('FilledButton.icon statesController', (WidgetTester tester) async {
testStatesController(const Icon(Icons.add), tester); testStatesController(const Icon(Icons.add), tester);
}); });
testWidgetsWithLeakTracking('Disabled FilledButton statesController', (WidgetTester tester) async { testWidgets('Disabled FilledButton statesController', (WidgetTester tester) async {
int count = 0; int count = 0;
void valueChanged() { void valueChanged() {
count += 1; count += 1;

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('FilledButtonThemeData lerp special cases', () { test('FilledButtonThemeData lerp special cases', () {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
/// Adds the basic requirements for a Chip. /// Adds the basic requirements for a Chip.
Widget wrapForChip({ Widget wrapForChip({

View File

@ -5,8 +5,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
final Key blockKey = UniqueKey(); final Key blockKey = UniqueKey();
const double expandedAppbarHeight = 250.0; const double expandedAppbarHeight = 250.0;
@ -51,7 +50,7 @@ void main() {
expect(topAfterScroll.dy, equals(0.0)); expect(topAfterScroll.dy, equals(0.0));
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.fuchsia })); }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.fuchsia }));
testWidgetsWithLeakTracking('FlexibleSpaceBar collapse mode pin', (WidgetTester tester) async { testWidgets('FlexibleSpaceBar collapse mode pin', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(platform: debugDefaultTargetPlatformOverride), theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
@ -89,7 +88,7 @@ void main() {
expect(topAfterScroll.dy, equals(-100.0)); expect(topAfterScroll.dy, equals(-100.0));
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.fuchsia })); }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.fuchsia }));
testWidgetsWithLeakTracking('FlexibleSpaceBar collapse mode parallax', (WidgetTester tester) async { testWidgets('FlexibleSpaceBar collapse mode parallax', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(platform: debugDefaultTargetPlatformOverride), theme: ThemeData(platform: debugDefaultTargetPlatformOverride),

View File

@ -9,8 +9,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
final Key blockKey = UniqueKey(); final Key blockKey = UniqueKey();
const double expandedAppbarHeight = 250.0; const double expandedAppbarHeight = 250.0;
@ -92,7 +91,7 @@ void main() {
); );
}); });
testWidgetsWithLeakTracking('FlexibleSpaceBar stretch mode fadeTitle', (WidgetTester tester) async { testWidgets('FlexibleSpaceBar stretch mode fadeTitle', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
@ -136,7 +135,7 @@ void main() {
expect(opacityWidget.opacity, equals(0.0)); expect(opacityWidget.opacity, equals(0.0));
}); });
testWidgetsWithLeakTracking('FlexibleSpaceBar stretch mode ignored for non-overscroll physics', (WidgetTester tester) async { testWidgets('FlexibleSpaceBar stretch mode ignored for non-overscroll physics', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(

View File

@ -10,8 +10,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {

View File

@ -7,8 +7,7 @@ import 'dart:math';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
group('Basic floating action button locations', () { group('Basic floating action button locations', () {
@ -185,7 +184,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}); });
testWidgetsWithLeakTracking('interrupting motion towards the StartTop location.', (WidgetTester tester) async { testWidgets('interrupting motion towards the StartTop location.', (WidgetTester tester) async {
await tester.pumpWidget(_buildFrame(location: FloatingActionButtonLocation.centerFloat, listener: geometryListener)); await tester.pumpWidget(_buildFrame(location: FloatingActionButtonLocation.centerFloat, listener: geometryListener));
setupListener(tester); setupListener(tester);
@ -198,7 +197,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}); });
testWidgetsWithLeakTracking('interrupting entrance to remove the fab.', (WidgetTester tester) async { testWidgets('interrupting entrance to remove the fab.', (WidgetTester tester) async {
await tester.pumpWidget(_buildFrame(fab: null, location: FloatingActionButtonLocation.centerFloat, listener: geometryListener)); await tester.pumpWidget(_buildFrame(fab: null, location: FloatingActionButtonLocation.centerFloat, listener: geometryListener));
setupListener(tester); setupListener(tester);
@ -217,7 +216,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}); });
testWidgetsWithLeakTracking('interrupting entrance of a new fab.', (WidgetTester tester) async { testWidgets('interrupting entrance of a new fab.', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
_buildFrame( _buildFrame(
fab: null, fab: null,

View File

@ -13,8 +13,7 @@ import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
@ -326,7 +325,7 @@ void main() {
expect(tester.widget<PhysicalShape>(find.byType(PhysicalShape)).elevation, 6.0); expect(tester.widget<PhysicalShape>(find.byType(PhysicalShape)).elevation, 6.0);
}); });
testWidgetsWithLeakTracking('Floating Action Button states elevation', (WidgetTester tester) async { testWidgets('Floating Action Button states elevation', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
await tester.pumpWidget( await tester.pumpWidget(
@ -368,6 +367,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(getFABWidget(fabFinder).elevation, 6); expect(getFABWidget(fabFinder).elevation, 6);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('FlatActionButton mini size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async { testWidgetsWithLeakTracking('FlatActionButton mini size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async {
@ -785,7 +786,7 @@ void main() {
}); });
// This test prevents https://github.com/flutter/flutter/issues/20483 // This test prevents https://github.com/flutter/flutter/issues/20483
testWidgetsWithLeakTracking('Floating Action Button clips ink splash and highlight', (WidgetTester tester) async { testWidgets('Floating Action Button clips ink splash and highlight', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
@ -909,6 +910,8 @@ void main() {
tester.renderObject(find.byType(FloatingActionButton)), tester.renderObject(find.byType(FloatingActionButton)),
paintsExactlyCountTimes(#clipPath, 0), paintsExactlyCountTimes(#clipPath, 0),
); );
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Can find FloatingActionButton semantics', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can find FloatingActionButton semantics', (WidgetTester tester) async {
@ -1164,7 +1167,7 @@ void main() {
expect(tester.widget<PhysicalShape>(find.byType(PhysicalShape)).elevation, 6.0); expect(tester.widget<PhysicalShape>(find.byType(PhysicalShape)).elevation, 6.0);
}); });
testWidgetsWithLeakTracking('Floating Action Button states elevation', (WidgetTester tester) async { testWidgets('Floating Action Button states elevation', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
await tester.pumpWidget( await tester.pumpWidget(
@ -1206,6 +1209,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(getFABWidget(fabFinder).elevation, 12); expect(getFABWidget(fabFinder).elevation, 12);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('FloatingActionButton.isExtended', (WidgetTester tester) async { testWidgetsWithLeakTracking('FloatingActionButton.isExtended', (WidgetTester tester) async {
@ -1327,7 +1332,7 @@ void main() {
// This test prevents https://github.com/flutter/flutter/issues/20483 // This test prevents https://github.com/flutter/flutter/issues/20483
testWidgetsWithLeakTracking('Floating Action Button clips ink splash and highlight', (WidgetTester tester) async { testWidgets('Floating Action Button clips ink splash and highlight', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(

View File

@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('FloatingActionButtonThemeData copyWith, ==, hashCode basics', () { test('FloatingActionButtonThemeData copyWith, ==, hashCode basics', () {

View File

@ -9,8 +9,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('Flutter Logo golden test', (WidgetTester tester) async { testWidgetsWithLeakTracking('Flutter Logo golden test', (WidgetTester tester) async {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('GridTile control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('GridTile control test', (WidgetTester tester) async {

View File

@ -7,8 +7,7 @@ import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
@ -100,13 +99,14 @@ void main() {
testWidgetsWithLeakTracking('when both iconSize and IconTheme.of(context).size are null, size falls back to 24.0', (WidgetTester tester) async { testWidgetsWithLeakTracking('when both iconSize and IconTheme.of(context).size are null, size falls back to 24.0', (WidgetTester tester) async {
final bool material3 = theme.useMaterial3; final bool material3 = theme.useMaterial3;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
useMaterial3: material3, useMaterial3: material3,
child: IconTheme( child: IconTheme(
data: const IconThemeData(), data: const IconThemeData(),
child: IconButton( child: IconButton(
focusNode: FocusNode(debugLabel: 'Ink Focus'), focusNode: focusNode,
onPressed: mockOnPressedFunction.handler, onPressed: mockOnPressedFunction.handler,
icon: const Icon(Icons.link), icon: const Icon(Icons.link),
), ),
@ -116,6 +116,8 @@ void main() {
final RenderBox icon = tester.renderObject(find.byType(Icon)); final RenderBox icon = tester.renderObject(find.byType(Icon));
expect(icon.size, const Size(24.0, 24.0)); expect(icon.size, const Size(24.0, 24.0));
focusNode.dispose();
}); });
testWidgets('when null, iconSize is overridden by closest IconTheme', (WidgetTester tester) async { testWidgets('when null, iconSize is overridden by closest IconTheme', (WidgetTester tester) async {
@ -739,6 +741,8 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('IconButton keeps focus when disabled in directional navigation mode.', (WidgetTester tester) async { testWidgetsWithLeakTracking('IconButton keeps focus when disabled in directional navigation mode.', (WidgetTester tester) async {
@ -781,6 +785,8 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking("Disabled IconButton can't be traversed to when disabled.", (WidgetTester tester) async { testWidgetsWithLeakTracking("Disabled IconButton can't be traversed to when disabled.", (WidgetTester tester) async {
@ -817,6 +823,9 @@ void main() {
expect(focusNode1.hasPrimaryFocus, isTrue); expect(focusNode1.hasPrimaryFocus, isTrue);
expect(focusNode2.hasPrimaryFocus, isFalse); expect(focusNode2.hasPrimaryFocus, isFalse);
focusNode1.dispose();
focusNode2.dispose();
}); });
group('feedback', () { group('feedback', () {
@ -1240,6 +1249,8 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('IconButton.fill defaults - M3', (WidgetTester tester) async { testWidgetsWithLeakTracking('IconButton.fill defaults - M3', (WidgetTester tester) async {
@ -1379,6 +1390,8 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Toggleable IconButton.fill defaults - M3', (WidgetTester tester) async { testWidgetsWithLeakTracking('Toggleable IconButton.fill defaults - M3', (WidgetTester tester) async {
@ -1633,6 +1646,8 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Toggleable IconButton.filledTonal defaults - M3', (WidgetTester tester) async { testWidgetsWithLeakTracking('Toggleable IconButton.filledTonal defaults - M3', (WidgetTester tester) async {
@ -1887,6 +1902,8 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08))); expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Toggleable IconButton.outlined defaults - M3', (WidgetTester tester) async { testWidgetsWithLeakTracking('Toggleable IconButton.outlined defaults - M3', (WidgetTester tester) async {
@ -2047,6 +2064,8 @@ void main() {
await expectLater(tester, meetsGuideline(textContrastGuideline)); await expectLater(tester, meetsGuideline(textContrastGuideline));
await gesture.removePointer(); await gesture.removePointer();
focusNode.dispose();
}, },
skip: isBrowser, // https://github.com/flutter/flutter/issues/44115 skip: isBrowser, // https://github.com/flutter/flutter/issues/44115
); );
@ -2135,6 +2154,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(iconColor(), pressedColor); expect(iconColor(), pressedColor);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does IconButton contribute semantics - M3', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does IconButton contribute semantics - M3', (WidgetTester tester) async {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('IconButtonThemeData lerp special cases', () { test('IconButtonThemeData lerp special cases', () {

View File

@ -12,10 +12,9 @@ import 'package:file/local.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('IconData object test', (WidgetTester tester) async { testWidgetsWithLeakTracking('IconData object test', (WidgetTester tester) async {
expect(Icons.account_balance, isNot(equals(Icons.account_box))); expect(Icons.account_balance, isNot(equals(Icons.account_box)));

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('The Ink widget expands when no dimensions are set', (WidgetTester tester) async { testWidgetsWithLeakTracking('The Ink widget expands when no dimensions are set', (WidgetTester tester) async {
@ -271,7 +270,7 @@ void main() {
await gesture.up(); await gesture.up();
}); });
testWidgetsWithLeakTracking('The InkWell widget renders an SelectAction or ActivateAction-induced ink ripple', (WidgetTester tester) async { testWidgets('The InkWell widget renders an SelectAction or ActivateAction-induced ink ripple', (WidgetTester tester) async {
const Color highlightColor = Color(0xAAFF0000); const Color highlightColor = Color(0xAAFF0000);
const Color splashColor = Color(0xB40000FF); const Color splashColor = Color(0xB40000FF);
const BorderRadius borderRadius = BorderRadius.all(Radius.circular(6.0)); const BorderRadius borderRadius = BorderRadius.all(Radius.circular(6.0));
@ -454,7 +453,7 @@ void main() {
})); }));
}); });
testWidgetsWithLeakTracking('The InkWell widget on OverlayPortal does not throw', (WidgetTester tester) async { testWidgets('The InkWell widget on OverlayPortal does not throw', (WidgetTester tester) async {
final OverlayPortalController controller = OverlayPortalController(); final OverlayPortalController controller = OverlayPortalController();
controller.show(); controller.show();
await tester.pumpWidget( await tester.pumpWidget(

View File

@ -10,8 +10,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/constants.dart'; import 'package:flutter/src/foundation/constants.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('InkSparkle in a Button compiles and does not crash', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkSparkle in a Button compiles and does not crash', (WidgetTester tester) async {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
// Regression test for https://github.com/flutter/flutter/issues/21506. // Regression test for https://github.com/flutter/flutter/issues/21506.

View File

@ -7,8 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/src/services/keyboard_key.g.dart'; import 'package:flutter/src/services/keyboard_key.g.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
@ -250,6 +249,7 @@ void main() {
inkFeatures, inkFeatures,
paints ..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0xff0000ff)), paints ..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0xff0000ff)),
); );
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ink response changes color on focus with overlayColor', (WidgetTester tester) async { testWidgetsWithLeakTracking('ink response changes color on focus with overlayColor', (WidgetTester tester) async {
@ -298,6 +298,7 @@ void main() {
inkFeatures, inkFeatures,
paints..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0xff0000ff)), paints..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0xff0000ff)),
); );
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ink well changes color on pressed with overlayColor', (WidgetTester tester) async { testWidgetsWithLeakTracking('ink well changes color on pressed with overlayColor', (WidgetTester tester) async {
@ -370,6 +371,7 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..circle(x: 50, y: 50, color: splashColor)); expect(inkFeatures, paints..circle(x: 50, y: 50, color: splashColor));
await gesture.up(); await gesture.up();
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ink response splashColor matches resolved overlayColor for MaterialState.pressed', (WidgetTester tester) async { testWidgetsWithLeakTracking('ink response splashColor matches resolved overlayColor for MaterialState.pressed', (WidgetTester tester) async {
@ -419,6 +421,7 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..circle(x: 50, y: 50, color: splashColor)); expect(inkFeatures, paints..circle(x: 50, y: 50, color: splashColor));
await gesture.up(); await gesture.up();
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ink response uses radius for focus highlight', (WidgetTester tester) async { testWidgetsWithLeakTracking('ink response uses radius for focus highlight', (WidgetTester tester) async {
@ -449,6 +452,7 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff))); expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell uses borderRadius for focus highlight', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell uses borderRadius for focus highlight', (WidgetTester tester) async {
@ -485,6 +489,7 @@ void main() {
rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(10)), rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(10)),
color: const Color(0xff0000ff), color: const Color(0xff0000ff),
)); ));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell uses borderRadius for hover highlight', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell uses borderRadius for hover highlight', (WidgetTester tester) async {
@ -576,6 +581,7 @@ void main() {
sampleSize: 100, sampleSize: 100,
)), )),
); );
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell customBorder clips for hover highlight', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell customBorder clips for hover highlight', (WidgetTester tester) async {
@ -667,6 +673,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1)); expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff))); expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkResponse highlightShape can be updated', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkResponse highlightShape can be updated', (WidgetTester tester) async {
@ -708,6 +715,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0)); expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1)); expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell borderRadius can be updated', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell borderRadius can be updated', (WidgetTester tester) async {
@ -753,6 +761,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(30)), rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(30)),
color: const Color(0xff0000ff), color: const Color(0xff0000ff),
)); ));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell customBorder can be updated', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell customBorder can be updated', (WidgetTester tester) async {
@ -820,6 +829,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
sampleSize: 100, sampleSize: 100,
)), )),
); );
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell splash customBorder can be updated', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell splash customBorder can be updated', (WidgetTester tester) async {
@ -908,6 +918,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
); );
await gesture.up(); await gesture.up();
focusNode.dispose();
}); });
testWidgetsWithLeakTracking("ink response doesn't change color on focus when on touch device", (WidgetTester tester) async { testWidgetsWithLeakTracking("ink response doesn't change color on focus when on touch device", (WidgetTester tester) async {
@ -940,6 +951,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawRect, 0)); expect(inkFeatures, paintsExactlyCountTimes(#drawRect, 0));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('InkWell.mouseCursor changes cursor on hover', (WidgetTester tester) async { testWidgetsWithLeakTracking('InkWell.mouseCursor changes cursor on hover', (WidgetTester tester) async {
@ -1029,7 +1041,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
}); });
testWidgetsWithLeakTracking('InkResponse containing selectable text changes mouse cursor when hovered', (WidgetTester tester) async { testWidgets('InkResponse containing selectable text changes mouse cursor when hovered', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/104595. // Regression test for https://github.com/flutter/flutter/issues/104595.
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: SelectionArea( home: SelectionArea(
@ -1218,6 +1230,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ink response accepts focus when disabled in directional navigation mode', (WidgetTester tester) async { testWidgetsWithLeakTracking('ink response accepts focus when disabled in directional navigation mode', (WidgetTester tester) async {
@ -1264,6 +1277,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking("ink response doesn't hover when disabled", (WidgetTester tester) async { testWidgetsWithLeakTracking("ink response doesn't hover when disabled", (WidgetTester tester) async {
@ -1317,6 +1331,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('When ink wells are nested, only the inner one is triggered by tap splash', (WidgetTester tester) async { testWidgetsWithLeakTracking('When ink wells are nested, only the inner one is triggered by tap splash', (WidgetTester tester) async {
@ -2071,7 +2086,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0)); expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
}); });
testWidgetsWithLeakTracking('InkWell dispose statesController', (WidgetTester tester) async { testWidgets('InkWell disposes statesController', (WidgetTester tester) async {
int tapCount = 0; int tapCount = 0;
Widget buildFrame(MaterialStatesController? statesController) { Widget buildFrame(MaterialStatesController? statesController) {
return MaterialApp( return MaterialApp(

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
/// Adds the basic requirements for a Chip. /// Adds the basic requirements for a Chip.
Widget wrapForChip({ Widget wrapForChip({
@ -241,6 +240,8 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('cannot be traversed to when disabled', (WidgetTester tester) async { testWidgetsWithLeakTracking('cannot be traversed to when disabled', (WidgetTester tester) async {
@ -276,6 +277,9 @@ void main() {
await tester.pump(); await tester.pump();
expect(focusNode1.hasPrimaryFocus, isTrue); expect(focusNode1.hasPrimaryFocus, isTrue);
expect(focusNode2.hasPrimaryFocus, isFalse); expect(focusNode2.hasPrimaryFocus, isFalse);
focusNode1.dispose();
focusNode2.dispose();
}); });
testWidgetsWithLeakTracking('Input chip check mark color is determined by platform brightness when light', (WidgetTester tester) async { testWidgetsWithLeakTracking('Input chip check mark color is determined by platform brightness when light', (WidgetTester tester) async {

View File

@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/clipboard_utils.dart'; import '../widgets/clipboard_utils.dart';
class TestMaterialLocalizations extends DefaultMaterialLocalizations { class TestMaterialLocalizations extends DefaultMaterialLocalizations {
@ -98,7 +97,7 @@ void main() {
group('InputDatePickerFormField', () { group('InputDatePickerFormField', () {
testWidgetsWithLeakTracking('Initial date is the default', (WidgetTester tester) async { testWidgets('Initial date is the default', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final DateTime initialDate = DateTime(2016, DateTime.february, 21); final DateTime initialDate = DateTime(2016, DateTime.february, 21);
DateTime? inputDate; DateTime? inputDate;
@ -112,7 +111,7 @@ void main() {
expect(inputDate, equals(initialDate)); expect(inputDate, equals(initialDate));
}); });
testWidgetsWithLeakTracking('Changing initial date is reflected in text value', (WidgetTester tester) async { testWidgets('Changing initial date is reflected in text value', (WidgetTester tester) async {
final DateTime initialDate = DateTime(2016, DateTime.february, 21); final DateTime initialDate = DateTime(2016, DateTime.february, 21);
final DateTime updatedInitialDate = DateTime(2016, DateTime.february, 23); final DateTime updatedInitialDate = DateTime(2016, DateTime.february, 23);
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
@ -127,7 +126,7 @@ void main() {
expect(textFieldController(tester).value.text, equals('02/23/2016')); expect(textFieldController(tester).value.text, equals('02/23/2016'));
}); });
testWidgetsWithLeakTracking('Valid date entry', (WidgetTester tester) async { testWidgets('Valid date entry', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
DateTime? inputDate; DateTime? inputDate;
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
@ -140,7 +139,7 @@ void main() {
expect(inputDate, equals(DateTime(2016, DateTime.february, 21))); expect(inputDate, equals(DateTime(2016, DateTime.february, 21)));
}); });
testWidgetsWithLeakTracking('Invalid text entry shows errorFormat text', (WidgetTester tester) async { testWidgets('Invalid text entry shows errorFormat text', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
DateTime? inputDate; DateTime? inputDate;
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
@ -167,7 +166,7 @@ void main() {
expect(find.text('That is not a date.'), findsOneWidget); expect(find.text('That is not a date.'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Valid text entry, but date outside first or last date shows bounds shows errorInvalid text', (WidgetTester tester) async { testWidgets('Valid text entry, but date outside first or last date shows bounds shows errorInvalid text', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
DateTime? inputDate; DateTime? inputDate;
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
@ -202,7 +201,7 @@ void main() {
expect(find.text('Not in given range.'), findsOneWidget); expect(find.text('Not in given range.'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('selectableDatePredicate will be used to show errorInvalid if date is not selectable', (WidgetTester tester) async { testWidgets('selectableDatePredicate will be used to show errorInvalid if date is not selectable', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
DateTime? inputDate; DateTime? inputDate;
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
@ -228,7 +227,7 @@ void main() {
expect(find.text('Out of range.'), findsNothing); expect(find.text('Out of range.'), findsNothing);
}); });
testWidgetsWithLeakTracking('Empty field shows hint text when focused', (WidgetTester tester) async { testWidgets('Empty field shows hint text when focused', (WidgetTester tester) async {
await tester.pumpWidget(inputDatePickerField()); await tester.pumpWidget(inputDatePickerField());
// Focus on it // Focus on it
await tester.tap(find.byType(TextField)); await tester.tap(find.byType(TextField));
@ -251,7 +250,7 @@ void main() {
expect(textOpacity(tester, 'Enter some date'), equals(0.0)); expect(textOpacity(tester, 'Enter some date'), equals(0.0));
}); });
testWidgetsWithLeakTracking('Label text', (WidgetTester tester) async { testWidgets('Label text', (WidgetTester tester) async {
await tester.pumpWidget(inputDatePickerField()); await tester.pumpWidget(inputDatePickerField());
// Default label // Default label
expect(find.text('Enter Date'), findsOneWidget); expect(find.text('Enter Date'), findsOneWidget);
@ -263,7 +262,7 @@ void main() {
expect(find.text('Give me a date!'), findsOneWidget); expect(find.text('Give me a date!'), findsOneWidget);
}); });
testWidgetsWithLeakTracking('Semantics', (WidgetTester tester) async { testWidgets('Semantics', (WidgetTester tester) async {
final SemanticsHandle semantics = tester.ensureSemantics(); final SemanticsHandle semantics = tester.ensureSemantics();
// Fill the clipboard so that the Paste option is available in the text // Fill the clipboard so that the Paste option is available in the text
@ -292,7 +291,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgetsWithLeakTracking('InputDecorationTheme is honored', (WidgetTester tester) async { testWidgets('InputDecorationTheme is honored', (WidgetTester tester) async {
const InputBorder border = InputBorder.none; const InputBorder border = InputBorder.none;
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith( theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
@ -326,7 +325,7 @@ void main() {
expect(containerColor, equals(Colors.transparent)); expect(containerColor, equals(Colors.transparent));
}); });
testWidgetsWithLeakTracking('Date text localization', (WidgetTester tester) async { testWidgets('Date text localization', (WidgetTester tester) async {
final Iterable<LocalizationsDelegate<dynamic>> delegates = <LocalizationsDelegate<dynamic>>[ final Iterable<LocalizationsDelegate<dynamic>> delegates = <LocalizationsDelegate<dynamic>>[
TestMaterialLocalizationsDelegate(), TestMaterialLocalizationsDelegate(),
DefaultWidgetsLocalizations.delegate, DefaultWidgetsLocalizations.delegate,
@ -349,7 +348,7 @@ void main() {
); );
}); });
testWidgetsWithLeakTracking('when an empty date is entered and acceptEmptyDate is true, then errorFormatText is not shown', (WidgetTester tester) async { testWidgets('when an empty date is entered and acceptEmptyDate is true, then errorFormatText is not shown', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
const String errorFormatText = 'That is not a date.'; const String errorFormatText = 'That is not a date.';
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(
@ -364,7 +363,7 @@ void main() {
expect(find.text(errorFormatText), findsNothing); expect(find.text(errorFormatText), findsNothing);
}); });
testWidgetsWithLeakTracking('when an empty date is entered and acceptEmptyDate is false, then errorFormatText is shown', (WidgetTester tester) async { testWidgets('when an empty date is entered and acceptEmptyDate is false, then errorFormatText is shown', (WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); final GlobalKey<FormState> formKey = GlobalKey<FormState>();
const String errorFormatText = 'That is not a date.'; const String errorFormatText = 'That is not a date.';
await tester.pumpWidget(inputDatePickerField( await tester.pumpWidget(inputDatePickerField(

View File

@ -10,8 +10,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart'; import 'feedback_tester.dart';
@ -906,6 +905,8 @@ void main() {
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
), ),
); );
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('ListTile can be hovered and has correct hover color', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListTile can be hovered and has correct hover color', (WidgetTester tester) async {
@ -1236,6 +1237,8 @@ void main() {
await tester.pump(); await tester.pump();
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('ListTile respects tileColor & selectedTileColor', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListTile respects tileColor & selectedTileColor', (WidgetTester tester) async {

View File

@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
class TestIcon extends StatefulWidget { class TestIcon extends StatefulWidget {
const TestIcon({ super.key }); const TestIcon({ super.key });
@ -568,7 +567,7 @@ void main() {
expect(find.byType(Material), paints..rect(color: selectedTileColor)); expect(find.byType(Material), paints..rect(color: selectedTileColor));
}); });
testWidgetsWithLeakTracking('ListTile uses ListTileTheme shape in a drawer', (WidgetTester tester) async { testWidgets('ListTile uses ListTileTheme shape in a drawer', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/106303 // This is a regression test for https://github.com/flutter/flutter/issues/106303
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('English translations exist for all MaterialLocalizations properties', (WidgetTester tester) async { testWidgetsWithLeakTracking('English translations exist for all MaterialLocalizations properties', (WidgetTester tester) async {

View File

@ -9,8 +9,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
final MagnifierController magnifierController = MagnifierController(); final MagnifierController magnifierController = MagnifierController();
const Rect reasonableTextField = Rect.fromLTRB(50, 100, 200, 100); const Rect reasonableTextField = Rect.fromLTRB(50, 100, 200, 100);
@ -112,7 +110,7 @@ void main() {
group('magnifier', () { group('magnifier', () {
group('position', () { group('position', () {
testWidgetsWithLeakTracking( testWidgets(
'should be at gesture position if does not violate any positioning rules', 'should be at gesture position if does not violate any positioning rules',
(WidgetTester tester) async { (WidgetTester tester) async {
final Key textField = UniqueKey(); final Key textField = UniqueKey();
@ -168,7 +166,7 @@ void main() {
); );
}); });
testWidgetsWithLeakTracking( testWidgets(
'should never move outside the right bounds of the editing line', 'should never move outside the right bounds of the editing line',
(WidgetTester tester) async { (WidgetTester tester) async {
const double gestureOutsideLine = 100; const double gestureOutsideLine = 100;
@ -201,7 +199,7 @@ void main() {
lessThanOrEqualTo(reasonableTextField.right)); lessThanOrEqualTo(reasonableTextField.right));
}); });
testWidgetsWithLeakTracking( testWidgets(
'should never move outside the left bounds of the editing line', 'should never move outside the left bounds of the editing line',
(WidgetTester tester) async { (WidgetTester tester) async {
const double gestureOutsideLine = 100; const double gestureOutsideLine = 100;
@ -233,7 +231,7 @@ void main() {
greaterThanOrEqualTo(reasonableTextField.left)); greaterThanOrEqualTo(reasonableTextField.left));
}); });
testWidgetsWithLeakTracking('should position vertically at the center of the line', (WidgetTester tester) async { testWidgets('should position vertically at the center of the line', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp( await tester.pumpWidget(const MaterialApp(
home: Placeholder(), home: Placeholder(),
)); ));
@ -256,7 +254,7 @@ void main() {
reasonableTextField.center.dy - basicOffset.dy); reasonableTextField.center.dy - basicOffset.dy);
}); });
testWidgetsWithLeakTracking('should reposition vertically if mashed against the ceiling', testWidgets('should reposition vertically if mashed against the ceiling',
(WidgetTester tester) async { (WidgetTester tester) async {
final Rect topOfScreenTextFieldRect = final Rect topOfScreenTextFieldRect =
Rect.fromPoints(Offset.zero, const Offset(200, 0)); Rect.fromPoints(Offset.zero, const Offset(200, 0));
@ -291,7 +289,7 @@ void main() {
return magnifier.additionalFocalPointOffset; return magnifier.additionalFocalPointOffset;
} }
testWidgetsWithLeakTracking( testWidgets(
'should shift focal point so that the lens sees nothing out of bounds', 'should shift focal point so that the lens sees nothing out of bounds',
(WidgetTester tester) async { (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp( await tester.pumpWidget(const MaterialApp(
@ -319,7 +317,7 @@ void main() {
lessThan(reasonableTextField.left)); lessThan(reasonableTextField.left));
}); });
testWidgetsWithLeakTracking( testWidgets(
'focal point should shift if mashed against the top to always point to text', 'focal point should shift if mashed against the top to always point to text',
(WidgetTester tester) async { (WidgetTester tester) async {
final Rect topOfScreenTextFieldRect = final Rect topOfScreenTextFieldRect =
@ -356,7 +354,7 @@ void main() {
return animatedPositioned.duration.compareTo(Duration.zero) != 0; return animatedPositioned.duration.compareTo(Duration.zero) != 0;
} }
testWidgetsWithLeakTracking('should not be animated on the initial state', testWidgets('should not be animated on the initial state',
(WidgetTester tester) async { (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp( await tester.pumpWidget(const MaterialApp(
home: Placeholder(), home: Placeholder(),
@ -381,7 +379,7 @@ void main() {
expect(getIsAnimated(tester), false); expect(getIsAnimated(tester), false);
}); });
testWidgetsWithLeakTracking('should not be animated on horizontal shifts', testWidgets('should not be animated on horizontal shifts',
(WidgetTester tester) async { (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp( await tester.pumpWidget(const MaterialApp(
home: Placeholder(), home: Placeholder(),
@ -415,7 +413,7 @@ void main() {
expect(getIsAnimated(tester), false); expect(getIsAnimated(tester), false);
}); });
testWidgetsWithLeakTracking('should be animated on vertical shifts', testWidgets('should be animated on vertical shifts',
(WidgetTester tester) async { (WidgetTester tester) async {
const Offset verticalShift = Offset(0, 200); const Offset verticalShift = Offset(0, 200);
@ -451,7 +449,7 @@ void main() {
expect(getIsAnimated(tester), true); expect(getIsAnimated(tester), true);
}); });
testWidgetsWithLeakTracking('should stop being animated when timer is up', testWidgets('should stop being animated when timer is up',
(WidgetTester tester) async { (WidgetTester tester) async {
const Offset verticalShift = Offset(0, 200); const Offset verticalShift = Offset(0, 200);

View File

@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {
@ -143,6 +142,8 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('MaterialButton elevation and colors have proper precedence', (WidgetTester tester) async { testWidgetsWithLeakTracking('MaterialButton elevation and colors have proper precedence', (WidgetTester tester) async {
@ -215,6 +216,8 @@ void main() {
expect(inkFeatures, paints..rect(color: focusColor)..rect(color: highlightColor)); expect(inkFeatures, paints..rect(color: focusColor)..rect(color: highlightColor));
expect(material.elevation, equals(highlightElevation)); expect(material.elevation, equals(highlightElevation));
await gesture2.up(); await gesture2.up();
focusNode.dispose();
}); });
testWidgetsWithLeakTracking("MaterialButton's disabledColor takes precedence over its default disabled color.", (WidgetTester tester) async { testWidgetsWithLeakTracking("MaterialButton's disabledColor takes precedence over its default disabled color.", (WidgetTester tester) async {
@ -299,6 +302,8 @@ void main() {
await tester.pump(); await tester.pump();
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('MaterialButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async { testWidgetsWithLeakTracking('MaterialButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {

View File

@ -6,8 +6,7 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
const Key key = Key('testContainer'); const Key key = Key('testContainer');
const Color trueColor = Colors.red; const Color trueColor = Colors.red;

View File

@ -10,8 +10,7 @@ library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/test_border.dart' show TestBorder; import '../widgets/test_border.dart' show TestBorder;
class NotifyMaterial extends StatelessWidget { class NotifyMaterial extends StatelessWidget {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
void onPressed(TestMenu item) {} void onPressed(TestMenu item) {}
@ -54,7 +53,7 @@ void main() {
expect(identical(MenuBarThemeData.lerp(data, data, 0.5), data), true); expect(identical(MenuBarThemeData.lerp(data, data, 0.5), data), true);
}); });
testWidgetsWithLeakTracking('theme is honored', (WidgetTester tester) async { testWidgets('theme is honored', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),

View File

@ -5,7 +5,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
Finder findMenuPanels() { Finder findMenuPanels() {
@ -43,7 +42,7 @@ void main() {
expect(identical(MenuStyle.lerp(data, data, 0.5), data), true); expect(identical(MenuStyle.lerp(data, data, 0.5), data), true);
}); });
testWidgetsWithLeakTracking('fixedSize affects geometry', (WidgetTester tester) async { testWidgets('fixedSize affects geometry', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
@ -86,7 +85,7 @@ void main() {
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0))); expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
}); });
testWidgetsWithLeakTracking('maximumSize affects geometry', (WidgetTester tester) async { testWidgets('maximumSize affects geometry', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
@ -129,7 +128,7 @@ void main() {
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0))); expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
}); });
testWidgetsWithLeakTracking('minimumSize affects geometry', (WidgetTester tester) async { testWidgets('minimumSize affects geometry', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
@ -172,7 +171,7 @@ void main() {
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(300.0, 300.0))); expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(300.0, 300.0)));
}); });
testWidgetsWithLeakTracking('Material parameters are honored', (WidgetTester tester) async { testWidgets('Material parameters are honored', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
@ -238,7 +237,7 @@ void main() {
expect(panelPadding.padding, equals(const EdgeInsets.all(20))); expect(panelPadding.padding, equals(const EdgeInsets.all(20)));
}); });
testWidgetsWithLeakTracking('visual density', (WidgetTester tester) async { testWidgets('visual density', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),

View File

@ -4,8 +4,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
void onPressed(TestMenu item) {} void onPressed(TestMenu item) {}
@ -54,7 +54,7 @@ void main() {
expect(identical(MenuThemeData.lerp(data, data, 0.5), data), true); expect(identical(MenuThemeData.lerp(data, data, 0.5), data), true);
}); });
testWidgetsWithLeakTracking('theme is honored', (WidgetTester tester) async { testWidgets('theme is honored', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
@ -107,7 +107,8 @@ void main() {
expect(subMenuMaterial.color, equals(Colors.red)); expect(subMenuMaterial.color, equals(Colors.red));
}); });
testWidgetsWithLeakTracking('Constructor parameters override theme parameters', (WidgetTester tester) async { testWidgetsWithLeakTracking('Constructor parameters override theme parameters',
(WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
enum RadiusType { enum RadiusType {
Sharp, Sharp,
@ -80,7 +79,7 @@ void main() {
expect(box.size.height, equals(0)); expect(box.size.height, equals(0));
}); });
testWidgetsWithLeakTracking('MergeableMaterial update slice', (WidgetTester tester) async { testWidgets('MergeableMaterial update slice', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
home: Scaffold( home: Scaffold(
@ -234,7 +233,7 @@ void main() {
debugDisableShadows = true; debugDisableShadows = true;
}); });
testWidgetsWithLeakTracking('MergeableMaterial skips shadow for zero elevation', (WidgetTester tester) async { testWidgets('MergeableMaterial skips shadow for zero elevation', (WidgetTester tester) async {
debugDisableShadows = false; debugDisableShadows = false;
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
@ -1168,7 +1167,7 @@ void main() {
); );
} }
testWidgetsWithLeakTracking('MergeableMaterial dividers', (WidgetTester tester) async { testWidgets('MergeableMaterial dividers', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
@ -1330,7 +1329,7 @@ void main() {
expect(decoration.border!.top.color, dividerColor); expect(decoration.border!.top.color, dividerColor);
}); });
testWidgetsWithLeakTracking('MergeableMaterial respects MaterialSlice.color', (WidgetTester tester) async { testWidgets('MergeableMaterial respects MaterialSlice.color', (WidgetTester tester) async {
const Color themeCardColor = Colors.red; const Color themeCardColor = Colors.red;
const Color materialSliceColor = Colors.green; const Color materialSliceColor = Colors.green;

View File

@ -13,8 +13,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('Navigation bar updates destinations when tapped', (WidgetTester tester) async { testWidgetsWithLeakTracking('Navigation bar updates destinations when tapped', (WidgetTester tester) async {

View File

@ -11,8 +11,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('copyWith, ==, hashCode basics', () { test('copyWith, ==, hashCode basics', () {

View File

@ -5,10 +5,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('Navigation drawer updates destinations when tapped', testWidgets('Navigation drawer updates destinations when tapped',
(WidgetTester tester) async { (WidgetTester tester) async {
int mutatedIndex = -1; int mutatedIndex = -1;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@ -51,7 +49,7 @@ void main() {
expect(mutatedIndex, 0); expect(mutatedIndex, 0);
}); });
testWidgetsWithLeakTracking('NavigationDrawer can update background color', testWidgets('NavigationDrawer can update background color',
(WidgetTester tester) async { (WidgetTester tester) async {
const Color color = Colors.yellow; const Color color = Colors.yellow;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@ -84,7 +82,7 @@ void main() {
expect(_getMaterial(tester).color, equals(color)); expect(_getMaterial(tester).color, equals(color));
}); });
testWidgetsWithLeakTracking('NavigationDrawer can update elevation', testWidgets('NavigationDrawer can update elevation',
(WidgetTester tester) async { (WidgetTester tester) async {
const double elevation = 42.0; const double elevation = 42.0;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@ -116,7 +114,7 @@ void main() {
expect(_getMaterial(tester).elevation, equals(elevation)); expect(_getMaterial(tester).elevation, equals(elevation));
}); });
testWidgetsWithLeakTracking( testWidgets(
'NavigationDrawer uses proper defaults when no parameters are given', 'NavigationDrawer uses proper defaults when no parameters are given',
(WidgetTester tester) async { (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@ -165,7 +163,7 @@ void main() {
expect(iconBox.size, const Size(24.0, 24.0)); expect(iconBox.size, const Size(24.0, 24.0));
}); });
testWidgetsWithLeakTracking('Navigation drawer is scrollable', (WidgetTester tester) async { testWidgets('Navigation drawer is scrollable', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
widgetSetup(tester, 500, viewHeight: 300); widgetSetup(tester, 500, viewHeight: 300);
await tester.pumpWidget( await tester.pumpWidget(
@ -212,7 +210,7 @@ void main() {
expect(find.text('Label10'), findsNothing); expect(find.text('Label10'), findsNothing);
}); });
testWidgetsWithLeakTracking('Safe Area test', (WidgetTester tester) async { testWidgets('Safe Area test', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
const double viewHeight = 300; const double viewHeight = 300;
widgetSetup(tester, 500, viewHeight: viewHeight); widgetSetup(tester, 500, viewHeight: viewHeight);
@ -253,7 +251,7 @@ void main() {
expect(tester.getBottomRight(find.widgetWithText(NavigationDrawerDestination,'Label4')).dy, viewHeight); expect(tester.getBottomRight(find.widgetWithText(NavigationDrawerDestination,'Label4')).dy, viewHeight);
}); });
testWidgetsWithLeakTracking('Navigation drawer semantics', (WidgetTester tester) async { testWidgets('Navigation drawer semantics', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light()); final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
Widget widget({int selectedIndex = 0}) { Widget widget({int selectedIndex = 0}) {
@ -323,7 +321,7 @@ void main() {
); );
}); });
testWidgetsWithLeakTracking('Navigation destination updates indicator color and shape', (WidgetTester tester) async { testWidgets('Navigation destination updates indicator color and shape', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final ThemeData theme = ThemeData(useMaterial3: true); final ThemeData theme = ThemeData(useMaterial3: true);
const Color color = Color(0xff0000ff); const Color color = Color(0xff0000ff);
@ -374,7 +372,7 @@ void main() {
expect(_getInkWell(tester)?.customBorder, shape); expect(_getInkWell(tester)?.customBorder, shape);
}); });
testWidgetsWithLeakTracking('NavigationDrawer.tilePadding defaults to EdgeInsets.symmetric(horizontal: 12.0)', (WidgetTester tester) async { testWidgets('NavigationDrawer.tilePadding defaults to EdgeInsets.symmetric(horizontal: 12.0)', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
widgetSetup(tester, 3000, viewHeight: 3000); widgetSetup(tester, 3000, viewHeight: 3000);
final Widget widget = _buildWidget( final Widget widget = _buildWidget(

View File

@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {

View File

@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
void main() { void main() {
@ -227,6 +226,8 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(overlayColor(), paints..rect(color: theme.colorScheme.primary.withOpacity(0.12))); expect(overlayColor(), paints..rect(color: theme.colorScheme.primary.withOpacity(0.12)));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does OutlinedButton work with hover', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does OutlinedButton work with hover', (WidgetTester tester) async {
@ -285,6 +286,8 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('Does OutlinedButton work with autofocus', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does OutlinedButton work with autofocus', (WidgetTester tester) async {
@ -315,6 +318,8 @@ void main() {
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paints..rect(color: focusColor)); expect(inkFeatures, paints..rect(color: focusColor));
focusNode.dispose();
}); });
testWidgets('Default OutlinedButton meets a11y contrast guidelines', (WidgetTester tester) async { testWidgets('Default OutlinedButton meets a11y contrast guidelines', (WidgetTester tester) async {
@ -360,6 +365,8 @@ void main() {
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await expectLater(tester, meetsGuideline(textContrastGuideline)); await expectLater(tester, meetsGuideline(textContrastGuideline));
focusNode.dispose();
}, },
skip: isBrowser, // https://github.com/flutter/flutter/issues/44115 skip: isBrowser, // https://github.com/flutter/flutter/issues/44115
); );
@ -429,6 +436,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
await expectLater(tester, meetsGuideline(textContrastGuideline)); await expectLater(tester, meetsGuideline(textContrastGuideline));
focusNode.dispose();
}, },
skip: isBrowser, // https://github.com/flutter/flutter/issues/44115 skip: isBrowser, // https://github.com/flutter/flutter/issues/44115
); );
@ -498,6 +507,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(textColor(), pressedColor); expect(textColor(), pressedColor);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('OutlinedButton uses stateful color for icon color in different states', (WidgetTester tester) async { testWidgetsWithLeakTracking('OutlinedButton uses stateful color for icon color in different states', (WidgetTester tester) async {
@ -565,6 +576,8 @@ void main() {
await tester.pump(); // Start the splash and highlight animations. await tester.pump(); // Start the splash and highlight animations.
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way. await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
expect(iconColor(), pressedColor); expect(iconColor(), pressedColor);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('OutlinedButton uses stateful color for border color in different states', (WidgetTester tester) async { testWidgetsWithLeakTracking('OutlinedButton uses stateful color for border color in different states', (WidgetTester tester) async {
@ -633,6 +646,8 @@ void main() {
await gesture.down(center); await gesture.down(center);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(outlinedButton, paints..drrect(color: pressedColor)); expect(outlinedButton, paints..drrect(color: pressedColor));
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('OutlinedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async { testWidgetsWithLeakTracking('OutlinedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
@ -727,6 +742,8 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse); expect(focusNode.hasPrimaryFocus, isFalse);
focusNode.dispose();
}); });
testWidgetsWithLeakTracking('disabled and hovered OutlinedButton responds to mouse-exit', (WidgetTester tester) async { testWidgetsWithLeakTracking('disabled and hovered OutlinedButton responds to mouse-exit', (WidgetTester tester) async {
@ -818,6 +835,8 @@ void main() {
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking('When OutlinedButton disable, Can not set OutlinedButton focus.', (WidgetTester tester) async { testWidgetsWithLeakTracking('When OutlinedButton disable, Can not set OutlinedButton focus.', (WidgetTester tester) async {
@ -841,6 +860,8 @@ void main() {
expect(gotFocus, isFalse); expect(gotFocus, isFalse);
expect(node.hasFocus, isFalse); expect(node.hasFocus, isFalse);
node.dispose();
}); });
testWidgetsWithLeakTracking("Outline button doesn't crash if disabled during a gesture", (WidgetTester tester) async { testWidgetsWithLeakTracking("Outline button doesn't crash if disabled during a gesture", (WidgetTester tester) async {
@ -1816,7 +1837,7 @@ void main() {
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
}); });
testWidgetsWithLeakTracking('OutlinedButton in SelectionArea changes mouse cursor when hovered', (WidgetTester tester) async { testWidgets('OutlinedButton in SelectionArea changes mouse cursor when hovered', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/104595. // Regression test for https://github.com/flutter/flutter/issues/104595.
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: SelectionArea( home: SelectionArea(
@ -1969,15 +1990,15 @@ void main() {
await gesture.removePointer(); await gesture.removePointer();
} }
testWidgetsWithLeakTracking('OutlinedButton statesController', (WidgetTester tester) async { testWidgets('OutlinedButton statesController', (WidgetTester tester) async {
testStatesController(null, tester); testStatesController(null, tester);
}); });
testWidgetsWithLeakTracking('OutlinedButton.icon statesController', (WidgetTester tester) async { testWidgets('OutlinedButton.icon statesController', (WidgetTester tester) async {
testStatesController(const Icon(Icons.add), tester); testStatesController(const Icon(Icons.add), tester);
}); });
testWidgetsWithLeakTracking('Disabled OutlinedButton statesController', (WidgetTester tester) async { testWidgets('Disabled OutlinedButton statesController', (WidgetTester tester) async {
int count = 0; int count = 0;
void valueChanged() { void valueChanged() {
count += 1; count += 1;

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
test('OutlinedButtonThemeData lerp special cases', () { test('OutlinedButtonThemeData lerp special cases', () {

View File

@ -4,8 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
const Color kSelectedColor = Color(0xFF00FF00); const Color kSelectedColor = Color(0xFF00FF00);
const Color kUnselectedColor = Colors.transparent; const Color kUnselectedColor = Colors.transparent;
@ -208,7 +207,7 @@ void main() {
expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]); expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]);
}); });
testWidgetsWithLeakTracking('PageSelector indicatorSize', (WidgetTester tester) async { testWidgets('PageSelector indicatorSize', (WidgetTester tester) async {
final TabController tabController = TabController( final TabController tabController = TabController(
vsync: const TestVSync(), vsync: const TestVSync(),
initialIndex: 1, initialIndex: 1,

View File

@ -7,8 +7,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
testWidgetsWithLeakTracking('Default PageTransitionsTheme platform', (WidgetTester tester) async { testWidgetsWithLeakTracking('Default PageTransitionsTheme platform', (WidgetTester tester) async {

View File

@ -5,8 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../foundation/leak_tracking.dart';
void main() { void main() {
// Pumps and ensures that the BottomSheet animates non-linearly. // Pumps and ensures that the BottomSheet animates non-linearly.
@ -124,7 +123,7 @@ void main() {
expect(buildCount, equals(2)); expect(buildCount, equals(2));
}); });
testWidgetsWithLeakTracking('Verify that a persistent BottomSheet cannot be dismissed', (WidgetTester tester) async { testWidgets('Verify that a persistent BottomSheet cannot be dismissed', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: Scaffold( home: Scaffold(
body: const Center(child: Text('body')), body: const Center(child: Text('body')),
@ -187,7 +186,7 @@ void main() {
expect(find.text('Two'), findsNothing); expect(find.text('Two'), findsNothing);
}); });
testWidgetsWithLeakTracking('Verify DraggableScrollableSheet.shouldCloseOnMinExtent == false prevents dismissal', (WidgetTester tester) async { testWidgets('Verify DraggableScrollableSheet.shouldCloseOnMinExtent == false prevents dismissal', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
@ -299,7 +298,7 @@ void main() {
expect(find.text('Two'), findsNothing); expect(find.text('Two'), findsNothing);
}); });
testWidgetsWithLeakTracking('Verify that a persistent BottomSheet can fling up and hide the fab', (WidgetTester tester) async { testWidgets('Verify that a persistent BottomSheet can fling up and hide the fab', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
@ -410,7 +409,7 @@ void main() {
expect(find.text('Item 22'), findsNothing); expect(find.text('Item 22'), findsNothing);
}); });
testWidgetsWithLeakTracking('Verify that a scrollable BottomSheet hides the fab when scrolled up', (WidgetTester tester) async { testWidgets('Verify that a scrollable BottomSheet hides the fab when scrolled up', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
@ -590,7 +589,7 @@ void main() {
}); });
// Regression test for https://github.com/flutter/flutter/issues/71435 // Regression test for https://github.com/flutter/flutter/issues/71435
testWidgetsWithLeakTracking( testWidgets(
'Scaffold.bottomSheet should be updated without creating a new RO' 'Scaffold.bottomSheet should be updated without creating a new RO'
' when the new widget has the same key and type.', ' when the new widget has the same key and type.',
(WidgetTester tester) async { (WidgetTester tester) async {

Some files were not shown because too many files have changed in this diff Show More