Unpin leak_tracker and handle breaking changes in API. (#132352)
This commit is contained in:
parent
87de2c5e60
commit
a7b69b069f
@ -22,8 +22,8 @@ dev_dependencies:
|
||||
flutter_goldens:
|
||||
sdk: flutter
|
||||
fake_async: 1.3.1
|
||||
leak_tracker: 8.0.3
|
||||
leak_tracker_testing: 1.0.2
|
||||
leak_tracker: 9.0.4
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
@ -73,4 +74,4 @@ dev_dependencies:
|
||||
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"
|
||||
|
||||
# PUBSPEC CHECKSUM: 443a
|
||||
# PUBSPEC CHECKSUM: a63c
|
||||
|
@ -12,7 +12,6 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
|
||||
void main() {
|
||||
/*
|
||||
@ -20,7 +19,7 @@ void main() {
|
||||
* 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);
|
||||
|
||||
await tester.pumpFrames(
|
||||
@ -57,7 +56,7 @@ void main() {
|
||||
image.dispose();
|
||||
}, 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(
|
||||
frameSize: const Size(8, 2),
|
||||
allLayers: true,
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/animation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('awaiting animation controllers - using direct future', (WidgetTester tester) async {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
|
@ -11,8 +11,7 @@ import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
/*
|
||||
@ -80,7 +79,7 @@ void main() {
|
||||
// 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
|
||||
|
||||
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 List<Offset> taps = <Offset>[];
|
||||
Widget target({bool recording = true}) => Container(
|
||||
|
@ -7,6 +7,7 @@ import 'dart:async';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker/leak_tracker.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import '_goldens_io.dart'
|
||||
if (dart.library.html) '_goldens_web.dart' as flutter_goldens;
|
||||
@ -23,7 +24,10 @@ Future<void> testExecutable(FutureOr<void> Function() testMain) {
|
||||
// receive the event.
|
||||
WidgetController.hitTestWarningShouldBeFatal = true;
|
||||
|
||||
LeakTrackerGlobalSettings.warnForNonSupportedPlatforms = false;
|
||||
LeakTracking.warnForUnsupportedPlatforms = false;
|
||||
setLeakTrackingTestSettings(
|
||||
LeakTrackingTestSettings(switches: const Switches(disableNotGCed: true))
|
||||
);
|
||||
|
||||
// Enable golden file testing using Skia Gold.
|
||||
return flutter_goldens.testExecutable(testMain);
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestNotifier extends ChangeNotifier {
|
||||
void notify() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('debugPrintGestureArenaDiagnostics', (WidgetTester tester) async {
|
||||
|
@ -9,8 +9,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestResampleEventFlutterBinding extends AutomatedTestWidgetsFlutterBinding {
|
||||
@override
|
||||
|
@ -6,8 +6,7 @@ import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestResult {
|
||||
bool dragStarted = false;
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('kTouchSlop is evaluated in the global coordinate space when scaled up', (WidgetTester tester) async {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async {
|
||||
|
@ -7,12 +7,11 @@ import 'dart:math' as math;
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
group('Horizontal', () {
|
||||
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async {
|
||||
testWidgets('gets local coordinates', (WidgetTester tester) async {
|
||||
int dragCancelCount = 0;
|
||||
final List<DragDownDetails> downDetails = <DragDownDetails>[];
|
||||
final List<DragEndDetails> endDetails = <DragEndDetails>[];
|
||||
|
@ -5,10 +5,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async {
|
||||
testWidgets('gets local coordinates', (WidgetTester tester) async {
|
||||
final List<ScaleStartDetails> startDetails = <ScaleStartDetails>[];
|
||||
final List<ScaleUpdateDetails> updateDetails = <ScaleUpdateDetails>[];
|
||||
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('gets local coordinates', (WidgetTester tester) async {
|
||||
|
@ -10,8 +10,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
tearDown(() {
|
||||
@ -58,7 +57,7 @@ void main() {
|
||||
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();
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -141,7 +140,7 @@ void main() {
|
||||
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();
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -1477,7 +1476,7 @@ void main() {
|
||||
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 Size defaultSize = Size(800.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));
|
||||
});
|
||||
|
||||
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 Size defaultSize = Size(800.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));
|
||||
});
|
||||
|
||||
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 Size defaultSize = Size(800.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));
|
||||
});
|
||||
|
||||
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 Size defaultSize = Size(800.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));
|
||||
});
|
||||
|
||||
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
|
||||
final ThemeData theme = ThemeData(
|
||||
appBarTheme: const AppBarTheme(foregroundColor: Color(0xFFFFFFFF)),
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
/// Adds the basic requirements for a Chip.
|
||||
Widget wrapForChip({
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('ActionIconThemeData copyWith, ==, hashCode basics', () {
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/clipboard_utils.dart';
|
||||
import '../widgets/editable_text_utils.dart';
|
||||
import '../widgets/live_text_utils.dart';
|
||||
@ -112,7 +111,7 @@ void main() {
|
||||
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();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -233,7 +232,7 @@ void main() {
|
||||
);
|
||||
|
||||
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
|
||||
// selection menu.
|
||||
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
||||
@ -328,7 +327,7 @@ void main() {
|
||||
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';
|
||||
|
||||
await tester.pumpWidget(
|
||||
|
@ -9,8 +9,7 @@ import 'dart:math' as math show pi;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
class MockCanvas extends Fake implements Canvas {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking("builder doesn't get called if app doesn't change", (WidgetTester tester) async {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('BackButton control test', (WidgetTester tester) async {
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
|
||||
void main() {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('BadgeThemeData copyWith, ==, hashCode basics', () {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('MaterialBanner properties are respected', (WidgetTester tester) async {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('MaterialBannerThemeData copyWith, ==, hashCode basics', () {
|
||||
|
@ -10,8 +10,7 @@ library;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Material3 - Shadow effect is not doubled', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/123064
|
||||
|
@ -9,8 +9,7 @@ library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('BottomAppBarTheme lerp special cases', () {
|
||||
|
@ -12,9 +12,9 @@ import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.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 '../foundation/leak_tracking.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
|
@ -6,10 +6,9 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.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 '../foundation/leak_tracking.dart';
|
||||
|
||||
|
||||
void main() {
|
||||
test('BottomNavigationBarThemeData copyWith, ==, hashCode basics', () {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('BottomSheetThemeData copyWith, ==, hashCode basics', () {
|
||||
@ -171,7 +170,7 @@ void main() {
|
||||
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 persistentElevation = 7.0;
|
||||
const Color modalBackgroundColor = Colors.yellow;
|
||||
@ -250,7 +249,7 @@ void main() {
|
||||
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 darkElevation = 3.0;
|
||||
const Color lightBackgroundColor = Colors.green;
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('ButtonBar default control smoketest', (WidgetTester tester) async {
|
||||
@ -341,7 +340,7 @@ void main() {
|
||||
|
||||
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(
|
||||
const SingleChildScrollView(
|
||||
child: ListBody(
|
||||
@ -364,7 +363,7 @@ void main() {
|
||||
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(
|
||||
const SingleChildScrollView(
|
||||
child: ListBody(
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('ButtonStyle copyWith, merge, ==, hashCode basics', () {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -8,8 +8,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
Widget wrap({ required Widget child }) {
|
||||
@ -496,6 +495,8 @@ void main() {
|
||||
await tester.pump();
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('CheckboxListTile can be disabled', (WidgetTester tester) async {
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('CheckboxThemeData copyWith, ==, hashCode basics', () {
|
||||
@ -302,7 +301,7 @@ void main() {
|
||||
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 inactivePressedOverlayColor = Color(0xFF000002);
|
||||
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
@ -701,7 +700,7 @@ void main() {
|
||||
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 Widget test = Overlay(
|
||||
initialEntries: <OverlayEntry>[
|
||||
@ -877,7 +876,7 @@ void main() {
|
||||
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 keyB = GlobalKey();
|
||||
await tester.pumpWidget(
|
||||
@ -913,7 +912,7 @@ void main() {
|
||||
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 keyB = GlobalKey();
|
||||
await tester.pumpWidget(
|
||||
@ -2633,7 +2632,7 @@ void main() {
|
||||
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();
|
||||
|
||||
const Color pressedColor = Color(0x00000001);
|
||||
@ -2721,7 +2720,7 @@ void main() {
|
||||
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();
|
||||
|
||||
const Color pressedColor = Color(0x00000001);
|
||||
@ -2801,7 +2800,7 @@ void main() {
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
const Color pressedColor = Color(0x00000001);
|
||||
@ -2971,7 +2970,7 @@ void main() {
|
||||
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();
|
||||
OutlinedBorder? getShape(Set<MaterialState> states) {
|
||||
|
||||
@ -3339,7 +3338,7 @@ void main() {
|
||||
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');
|
||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||
const Color backgroundColor = Color(0xff00ff00);
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
RenderBox getMaterialBox(WidgetTester tester) {
|
||||
return tester.firstRenderObject<RenderBox>(
|
||||
@ -641,6 +640,8 @@ void main() {
|
||||
await tester.pumpWidget(chipWidget(enabled: false));
|
||||
await tester.pumpAndSettle();
|
||||
expect(textColor(), disabledColor);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Chip uses stateful border side from resolveWith pattern', (WidgetTester tester) async {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
RenderBox getMaterialBox(WidgetTester tester, Finder type) {
|
||||
return tester.firstRenderObject<RenderBox>(
|
||||
|
@ -12,8 +12,7 @@ import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../image_data.dart';
|
||||
import '../painting/mocks_for_image_cache.dart';
|
||||
|
||||
|
@ -11,9 +11,9 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.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 '../foundation/leak_tracking.dart';
|
||||
import 'data_table_test_utils.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('DataTableThemeData copyWith, ==, hashCode basics', () {
|
||||
|
@ -8,8 +8,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
void main() {
|
||||
@ -260,6 +259,7 @@ void main() {
|
||||
// https://github.com/flutter/flutter/issues/130354
|
||||
leakTrackingTestConfig: const LeakTrackingTestConfig(
|
||||
allowAllNotGCed: true,
|
||||
allowAllNotDisposed: true,
|
||||
));
|
||||
});
|
||||
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('debugCheckHasMaterial control test', (WidgetTester tester) async {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -9,8 +9,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
MaterialApp _buildAppWithDialog(
|
||||
@ -2338,7 +2337,7 @@ void main() {
|
||||
});
|
||||
|
||||
group('AlertDialog.scrollable: ', () {
|
||||
testWidgetsWithLeakTracking('Title is scrollable', (WidgetTester tester) async {
|
||||
testWidgets('Title is scrollable', (WidgetTester tester) async {
|
||||
final Key titleKey = UniqueKey();
|
||||
final AlertDialog dialog = AlertDialog(
|
||||
title: Container(
|
||||
@ -2378,7 +2377,7 @@ void main() {
|
||||
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 contentKey = UniqueKey();
|
||||
final AlertDialog dialog = AlertDialog(
|
||||
@ -2511,7 +2510,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('DialogRoute is state restorable', (WidgetTester tester) async {
|
||||
testWidgets('DialogRoute is state restorable', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
restorationScopeId: 'app',
|
||||
@ -2660,6 +2659,9 @@ void main() {
|
||||
expect(await previousFocus(), true);
|
||||
expect(okNode.hasFocus, true);
|
||||
expect(cancelNode.hasFocus, false);
|
||||
|
||||
cancelNode.dispose();
|
||||
okNode.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Adaptive AlertDialog shows correct widget on each platform', (WidgetTester tester) async {
|
||||
@ -2764,7 +2766,7 @@ void main() {
|
||||
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 cancelNode = FocusNode();
|
||||
|
||||
|
@ -5,11 +5,10 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('DrawerButton control test', (WidgetTester tester) async {
|
||||
testWidgets('DrawerButton control test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -171,7 +170,7 @@ void main() {
|
||||
handle.dispose();
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgetsWithLeakTracking('EndDrawerButton control test', (WidgetTester tester) async {
|
||||
testWidgets('EndDrawerButton control test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
|
@ -8,8 +8,6 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
|
||||
const List<String> menuItems = <String>['one', 'two', 'three', 'four'];
|
||||
void onChanged<T>(T _) { }
|
||||
final Type dropdownButtonType = DropdownButton<String>(
|
||||
@ -201,7 +199,7 @@ void main() {
|
||||
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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -239,7 +237,7 @@ void main() {
|
||||
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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -264,7 +262,7 @@ void main() {
|
||||
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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -314,7 +312,7 @@ void main() {
|
||||
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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -352,7 +350,7 @@ void main() {
|
||||
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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -392,7 +390,7 @@ void main() {
|
||||
});
|
||||
|
||||
// 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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -493,7 +491,7 @@ void main() {
|
||||
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();
|
||||
|
||||
// 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();
|
||||
|
||||
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 {
|
||||
final Key buttonKey = UniqueKey();
|
||||
const String value = 'two';
|
||||
@ -607,7 +605,7 @@ void main() {
|
||||
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
|
||||
final Key buttonKey = UniqueKey();
|
||||
const String value = 'two';
|
||||
@ -638,7 +636,7 @@ void main() {
|
||||
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';
|
||||
final UniqueKey itemKey = UniqueKey();
|
||||
|
||||
@ -676,7 +674,7 @@ void main() {
|
||||
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();
|
||||
|
||||
Widget build({ List<String>? items }) {
|
||||
@ -699,7 +697,7 @@ void main() {
|
||||
expect(find.text('disabled'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'DropdownButtonFormField - hint displays when the items list is '
|
||||
'empty, items is null, and disabledHint is null',
|
||||
(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();
|
||||
|
||||
Widget build({ List<String>? items }) {
|
||||
@ -743,7 +741,7 @@ void main() {
|
||||
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();
|
||||
|
||||
Widget build({ List<String>? items }) {
|
||||
@ -763,7 +761,7 @@ void main() {
|
||||
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();
|
||||
|
||||
Widget build({ List<String>? items, ValueChanged<String?>? onChanged }) {
|
||||
@ -781,7 +779,7 @@ void main() {
|
||||
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();
|
||||
|
||||
Widget build({ List<String>? items}) {
|
||||
@ -806,7 +804,7 @@ void main() {
|
||||
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 Icon customIcon = Icon(Icons.assessment, key: iconKey);
|
||||
|
||||
@ -839,7 +837,7 @@ void main() {
|
||||
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();
|
||||
debugDisableShadows = false;
|
||||
await tester.pumpWidget(buildFormFrame(
|
||||
@ -896,7 +894,7 @@ void main() {
|
||||
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']
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
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']
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
@ -1090,7 +1088,7 @@ void main() {
|
||||
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;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -1119,7 +1117,7 @@ void main() {
|
||||
expect(validateCalled, 1);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('DropdownButtonFormField - Custom button alignment', (WidgetTester tester) async {
|
||||
testWidgets('DropdownButtonFormField - Custom button alignment', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(buildFormFrame(
|
||||
buttonAlignment: AlignmentDirectional.center,
|
||||
items: <String>['one'],
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('DropdownMenuThemeData copyWith, ==, hashCode basics', () {
|
||||
@ -44,7 +43,7 @@ void main() {
|
||||
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();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -101,7 +100,7 @@ void main() {
|
||||
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(
|
||||
dropdownMenuTheme: DropdownMenuThemeData(
|
||||
textStyle: TextStyle(
|
||||
@ -180,7 +179,7 @@ void main() {
|
||||
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(
|
||||
textStyle: TextStyle(
|
||||
color: Colors.orange,
|
||||
@ -283,7 +282,7 @@ void main() {
|
||||
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(
|
||||
textStyle: TextStyle(
|
||||
color: Colors.orange,
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
@ -196,6 +195,7 @@ void main() {
|
||||
await gesture.moveTo(center);
|
||||
await tester.pumpAndSettle();
|
||||
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
||||
focusNode.dispose();
|
||||
},
|
||||
skip: isBrowser, // https://github.com/flutter/flutter/issues/44115
|
||||
);
|
||||
@ -259,6 +259,8 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
expect(elevation(), 1.0);
|
||||
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 {
|
||||
@ -334,6 +336,8 @@ void main() {
|
||||
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.
|
||||
expect(textColor(), pressedColor);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
|
||||
@ -410,6 +414,8 @@ void main() {
|
||||
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.
|
||||
expect(iconColor(), pressedColor);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('ElevatedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
|
||||
@ -534,6 +540,8 @@ void main() {
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('disabled and hovered ElevatedButton responds to mouse-exit', (WidgetTester tester) async {
|
||||
@ -625,6 +633,8 @@ void main() {
|
||||
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('When ElevatedButton disable, Can not set ElevatedButton focus.', (WidgetTester tester) async {
|
||||
@ -648,6 +658,9 @@ void main() {
|
||||
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
|
||||
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Does ElevatedButton contribute semantics', (WidgetTester tester) async {
|
||||
@ -1667,7 +1684,7 @@ void main() {
|
||||
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.
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
@ -1865,15 +1882,15 @@ void main() {
|
||||
await gesture.removePointer();
|
||||
}
|
||||
|
||||
testWidgetsWithLeakTracking('ElevatedButton statesController', (WidgetTester tester) async {
|
||||
testWidgets('ElevatedButton statesController', (WidgetTester tester) async {
|
||||
testStatesController(null, tester);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('ElevatedButton.icon statesController', (WidgetTester tester) async {
|
||||
testWidgets('ElevatedButton.icon statesController', (WidgetTester tester) async {
|
||||
testStatesController(const Icon(Icons.add), tester);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Disabled ElevatedButton statesController', (WidgetTester tester) async {
|
||||
testWidgets('Disabled ElevatedButton statesController', (WidgetTester tester) async {
|
||||
int count = 0;
|
||||
void valueChanged() {
|
||||
count += 1;
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('ElevatedButtonThemeData lerp special cases', () {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
Widget wrap({ required Widget child, ThemeData? theme }) {
|
||||
return MaterialApp(
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class SimpleExpansionPanelListTestWidget extends StatefulWidget {
|
||||
const SimpleExpansionPanelListTestWidget({
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestIcon extends StatefulWidget {
|
||||
const TestIcon({super.key});
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestIcon extends StatefulWidget {
|
||||
const TestIcon({super.key});
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
@ -340,6 +339,7 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
expect(elevation(), 0.0);
|
||||
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 {
|
||||
@ -405,6 +405,7 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
expect(elevation(), 0.0);
|
||||
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 {
|
||||
@ -480,6 +481,7 @@ void main() {
|
||||
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.
|
||||
expect(textColor(), pressedColor);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
|
||||
@ -556,6 +558,7 @@ void main() {
|
||||
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.
|
||||
expect(iconColor(), pressedColor);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('FilledButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
|
||||
@ -680,6 +683,7 @@ void main() {
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('disabled and hovered FilledButton responds to mouse-exit', (WidgetTester tester) async {
|
||||
@ -771,6 +775,7 @@ void main() {
|
||||
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('When FilledButton disable, Can not set FilledButton focus.', (WidgetTester tester) async {
|
||||
@ -794,6 +799,7 @@ void main() {
|
||||
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Does FilledButton contribute semantics', (WidgetTester tester) async {
|
||||
@ -1741,7 +1749,7 @@ void main() {
|
||||
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.
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
@ -1937,15 +1945,15 @@ void main() {
|
||||
await gesture.removePointer();
|
||||
}
|
||||
|
||||
testWidgetsWithLeakTracking('FilledButton statesController', (WidgetTester tester) async {
|
||||
testWidgets('FilledButton statesController', (WidgetTester tester) async {
|
||||
testStatesController(null, tester);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('FilledButton.icon statesController', (WidgetTester tester) async {
|
||||
testWidgets('FilledButton.icon statesController', (WidgetTester tester) async {
|
||||
testStatesController(const Icon(Icons.add), tester);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Disabled FilledButton statesController', (WidgetTester tester) async {
|
||||
testWidgets('Disabled FilledButton statesController', (WidgetTester tester) async {
|
||||
int count = 0;
|
||||
void valueChanged() {
|
||||
count += 1;
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('FilledButtonThemeData lerp special cases', () {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
/// Adds the basic requirements for a Chip.
|
||||
Widget wrapForChip({
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
final Key blockKey = UniqueKey();
|
||||
const double expandedAppbarHeight = 250.0;
|
||||
@ -51,7 +50,7 @@ void main() {
|
||||
expect(topAfterScroll.dy, equals(0.0));
|
||||
}, 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(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
|
||||
@ -89,7 +88,7 @@ void main() {
|
||||
expect(topAfterScroll.dy, equals(-100.0));
|
||||
}, 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(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
|
||||
|
@ -9,8 +9,7 @@ library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
final Key blockKey = UniqueKey();
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -136,7 +135,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
|
@ -10,8 +10,7 @@ library;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -7,8 +7,7 @@ import 'dart:math';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
group('Basic floating action button locations', () {
|
||||
@ -185,7 +184,7 @@ void main() {
|
||||
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));
|
||||
setupListener(tester);
|
||||
|
||||
@ -198,7 +197,7 @@ void main() {
|
||||
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));
|
||||
setupListener(tester);
|
||||
|
||||
@ -217,7 +216,7 @@ void main() {
|
||||
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(
|
||||
_buildFrame(
|
||||
fab: null,
|
||||
|
@ -13,8 +13,7 @@ import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
@ -326,7 +325,7 @@ void main() {
|
||||
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();
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -368,6 +367,8 @@ void main() {
|
||||
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.
|
||||
expect(getFABWidget(fabFinder).elevation, 6);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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
|
||||
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();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -909,6 +910,8 @@ void main() {
|
||||
tester.renderObject(find.byType(FloatingActionButton)),
|
||||
paintsExactlyCountTimes(#clipPath, 0),
|
||||
);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Can find FloatingActionButton semantics', (WidgetTester tester) async {
|
||||
@ -1164,7 +1167,7 @@ void main() {
|
||||
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();
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -1206,6 +1209,8 @@ void main() {
|
||||
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.
|
||||
expect(getFABWidget(fabFinder).elevation, 12);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('FloatingActionButton.isExtended', (WidgetTester tester) async {
|
||||
@ -1327,7 +1332,7 @@ void main() {
|
||||
|
||||
|
||||
// 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();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('FloatingActionButtonThemeData copyWith, ==, hashCode basics', () {
|
||||
|
@ -9,8 +9,7 @@ library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Flutter Logo golden test', (WidgetTester tester) async {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('GridTile control test', (WidgetTester tester) async {
|
||||
|
@ -7,8 +7,7 @@ import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_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 {
|
||||
final bool material3 = theme.useMaterial3;
|
||||
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
useMaterial3: material3,
|
||||
child: IconTheme(
|
||||
data: const IconThemeData(),
|
||||
child: IconButton(
|
||||
focusNode: FocusNode(debugLabel: 'Ink Focus'),
|
||||
focusNode: focusNode,
|
||||
onPressed: mockOnPressedFunction.handler,
|
||||
icon: const Icon(Icons.link),
|
||||
),
|
||||
@ -116,6 +116,8 @@ void main() {
|
||||
|
||||
final RenderBox icon = tester.renderObject(find.byType(Icon));
|
||||
expect(icon.size, const Size(24.0, 24.0));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgets('when null, iconSize is overridden by closest IconTheme', (WidgetTester tester) async {
|
||||
@ -739,6 +741,8 @@ void main() {
|
||||
);
|
||||
await tester.pump();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('IconButton keeps focus when disabled in directional navigation mode.', (WidgetTester tester) async {
|
||||
@ -781,6 +785,8 @@ void main() {
|
||||
);
|
||||
await tester.pump();
|
||||
expect(focusNode.hasPrimaryFocus, isTrue);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking("Disabled IconButton can't be traversed to when disabled.", (WidgetTester tester) async {
|
||||
@ -817,6 +823,9 @@ void main() {
|
||||
|
||||
expect(focusNode1.hasPrimaryFocus, isTrue);
|
||||
expect(focusNode2.hasPrimaryFocus, isFalse);
|
||||
|
||||
focusNode1.dispose();
|
||||
focusNode2.dispose();
|
||||
});
|
||||
|
||||
group('feedback', () {
|
||||
@ -1240,6 +1249,8 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.12)));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('IconButton.fill defaults - M3', (WidgetTester tester) async {
|
||||
@ -1379,6 +1390,8 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.12)));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Toggleable IconButton.fill defaults - M3', (WidgetTester tester) async {
|
||||
@ -1633,6 +1646,8 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.12)));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Toggleable IconButton.filledTonal defaults - M3', (WidgetTester tester) async {
|
||||
@ -1887,6 +1902,8 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Toggleable IconButton.outlined defaults - M3', (WidgetTester tester) async {
|
||||
@ -2047,6 +2064,8 @@ void main() {
|
||||
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
||||
|
||||
await gesture.removePointer();
|
||||
|
||||
focusNode.dispose();
|
||||
},
|
||||
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(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
||||
expect(iconColor(), pressedColor);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Does IconButton contribute semantics - M3', (WidgetTester tester) async {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('IconButtonThemeData lerp special cases', () {
|
||||
|
@ -12,10 +12,9 @@ import 'package:file/local.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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 '../foundation/leak_tracking.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('IconData object test', (WidgetTester tester) async {
|
||||
expect(Icons.account_balance, isNot(equals(Icons.account_box)));
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('The Ink widget expands when no dimensions are set', (WidgetTester tester) async {
|
||||
@ -271,7 +270,7 @@ void main() {
|
||||
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 splashColor = Color(0xB40000FF);
|
||||
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();
|
||||
controller.show();
|
||||
await tester.pumpWidget(
|
||||
|
@ -10,8 +10,7 @@ library;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/foundation/constants.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('InkSparkle in a Button compiles and does not crash', (WidgetTester tester) async {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/21506.
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/src/services/keyboard_key.g.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
@ -250,6 +249,7 @@ void main() {
|
||||
inkFeatures,
|
||||
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 {
|
||||
@ -298,6 +298,7 @@ void main() {
|
||||
inkFeatures,
|
||||
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 {
|
||||
@ -370,6 +371,7 @@ void main() {
|
||||
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||
expect(inkFeatures, paints..circle(x: 50, y: 50, color: splashColor));
|
||||
await gesture.up();
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..circle(x: 50, y: 50, color: splashColor));
|
||||
await gesture.up();
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('ink response uses radius for focus highlight', (WidgetTester tester) async {
|
||||
@ -449,6 +452,7 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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)),
|
||||
color: const Color(0xff0000ff),
|
||||
));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('InkWell uses borderRadius for hover highlight', (WidgetTester tester) async {
|
||||
@ -576,6 +581,7 @@ void main() {
|
||||
sampleSize: 100,
|
||||
)),
|
||||
);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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();
|
||||
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
|
||||
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('InkResponse highlightShape can be updated', (WidgetTester tester) async {
|
||||
@ -708,6 +715,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
|
||||
await tester.pumpAndSettle();
|
||||
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
|
||||
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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)),
|
||||
color: const Color(0xff0000ff),
|
||||
));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('InkWell customBorder can be updated', (WidgetTester tester) async {
|
||||
@ -820,6 +829,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
|
||||
sampleSize: 100,
|
||||
)),
|
||||
);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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();
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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();
|
||||
await tester.pumpAndSettle();
|
||||
expect(inkFeatures, paintsExactlyCountTimes(#drawRect, 0));
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
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.
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
@ -1218,6 +1230,7 @@ testWidgetsWithLeakTracking('InkResponse radius can be updated', (WidgetTester t
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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();
|
||||
expect(focusNode.hasPrimaryFocus, isTrue);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('InkWell dispose statesController', (WidgetTester tester) async {
|
||||
testWidgets('InkWell disposes statesController', (WidgetTester tester) async {
|
||||
int tapCount = 0;
|
||||
Widget buildFrame(MaterialStatesController? statesController) {
|
||||
return MaterialApp(
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
/// Adds the basic requirements for a Chip.
|
||||
Widget wrapForChip({
|
||||
@ -241,6 +240,8 @@ void main() {
|
||||
);
|
||||
await tester.pump();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('cannot be traversed to when disabled', (WidgetTester tester) async {
|
||||
@ -276,6 +277,9 @@ void main() {
|
||||
await tester.pump();
|
||||
expect(focusNode1.hasPrimaryFocus, isTrue);
|
||||
expect(focusNode2.hasPrimaryFocus, isFalse);
|
||||
|
||||
focusNode1.dispose();
|
||||
focusNode2.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Input chip check mark color is determined by platform brightness when light', (WidgetTester tester) async {
|
||||
|
@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import '../widgets/clipboard_utils.dart';
|
||||
|
||||
class TestMaterialLocalizations extends DefaultMaterialLocalizations {
|
||||
@ -98,7 +97,7 @@ void main() {
|
||||
|
||||
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 DateTime initialDate = DateTime(2016, DateTime.february, 21);
|
||||
DateTime? inputDate;
|
||||
@ -112,7 +111,7 @@ void main() {
|
||||
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 updatedInitialDate = DateTime(2016, DateTime.february, 23);
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
@ -127,7 +126,7 @@ void main() {
|
||||
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>();
|
||||
DateTime? inputDate;
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
@ -140,7 +139,7 @@ void main() {
|
||||
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>();
|
||||
DateTime? inputDate;
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
@ -167,7 +166,7 @@ void main() {
|
||||
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>();
|
||||
DateTime? inputDate;
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
@ -202,7 +201,7 @@ void main() {
|
||||
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>();
|
||||
DateTime? inputDate;
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
@ -228,7 +227,7 @@ void main() {
|
||||
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());
|
||||
// Focus on it
|
||||
await tester.tap(find.byType(TextField));
|
||||
@ -251,7 +250,7 @@ void main() {
|
||||
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());
|
||||
// Default label
|
||||
expect(find.text('Enter Date'), findsOneWidget);
|
||||
@ -263,7 +262,7 @@ void main() {
|
||||
expect(find.text('Give me a date!'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Semantics', (WidgetTester tester) async {
|
||||
testWidgets('Semantics', (WidgetTester tester) async {
|
||||
final SemanticsHandle semantics = tester.ensureSemantics();
|
||||
|
||||
// Fill the clipboard so that the Paste option is available in the text
|
||||
@ -292,7 +291,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('InputDecorationTheme is honored', (WidgetTester tester) async {
|
||||
testWidgets('InputDecorationTheme is honored', (WidgetTester tester) async {
|
||||
const InputBorder border = InputBorder.none;
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
|
||||
@ -326,7 +325,7 @@ void main() {
|
||||
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>>[
|
||||
TestMaterialLocalizationsDelegate(),
|
||||
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>();
|
||||
const String errorFormatText = 'That is not a date.';
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
@ -364,7 +363,7 @@ void main() {
|
||||
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>();
|
||||
const String errorFormatText = 'That is not a date.';
|
||||
await tester.pumpWidget(inputDatePickerField(
|
||||
|
@ -10,8 +10,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
@ -906,6 +905,8 @@ void main() {
|
||||
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 {
|
||||
@ -1236,6 +1237,8 @@ void main() {
|
||||
await tester.pump();
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('ListTile respects tileColor & selectedTileColor', (WidgetTester tester) async {
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestIcon extends StatefulWidget {
|
||||
const TestIcon({ super.key });
|
||||
@ -568,7 +567,7 @@ void main() {
|
||||
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
|
||||
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('English translations exist for all MaterialLocalizations properties', (WidgetTester tester) async {
|
||||
|
@ -9,8 +9,6 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
|
||||
void main() {
|
||||
final MagnifierController magnifierController = MagnifierController();
|
||||
const Rect reasonableTextField = Rect.fromLTRB(50, 100, 200, 100);
|
||||
@ -112,7 +110,7 @@ void main() {
|
||||
|
||||
group('magnifier', () {
|
||||
group('position', () {
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'should be at gesture position if does not violate any positioning rules',
|
||||
(WidgetTester tester) async {
|
||||
final Key textField = UniqueKey();
|
||||
@ -168,7 +166,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'should never move outside the right bounds of the editing line',
|
||||
(WidgetTester tester) async {
|
||||
const double gestureOutsideLine = 100;
|
||||
@ -201,7 +199,7 @@ void main() {
|
||||
lessThanOrEqualTo(reasonableTextField.right));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'should never move outside the left bounds of the editing line',
|
||||
(WidgetTester tester) async {
|
||||
const double gestureOutsideLine = 100;
|
||||
@ -233,7 +231,7 @@ void main() {
|
||||
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(
|
||||
home: Placeholder(),
|
||||
));
|
||||
@ -256,7 +254,7 @@ void main() {
|
||||
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 {
|
||||
final Rect topOfScreenTextFieldRect =
|
||||
Rect.fromPoints(Offset.zero, const Offset(200, 0));
|
||||
@ -291,7 +289,7 @@ void main() {
|
||||
return magnifier.additionalFocalPointOffset;
|
||||
}
|
||||
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'should shift focal point so that the lens sees nothing out of bounds',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(const MaterialApp(
|
||||
@ -319,7 +317,7 @@ void main() {
|
||||
lessThan(reasonableTextField.left));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'focal point should shift if mashed against the top to always point to text',
|
||||
(WidgetTester tester) async {
|
||||
final Rect topOfScreenTextFieldRect =
|
||||
@ -356,7 +354,7 @@ void main() {
|
||||
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 {
|
||||
await tester.pumpWidget(const MaterialApp(
|
||||
home: Placeholder(),
|
||||
@ -381,7 +379,7 @@ void main() {
|
||||
expect(getIsAnimated(tester), false);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('should not be animated on horizontal shifts',
|
||||
testWidgets('should not be animated on horizontal shifts',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(const MaterialApp(
|
||||
home: Placeholder(),
|
||||
@ -415,7 +413,7 @@ void main() {
|
||||
expect(getIsAnimated(tester), false);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('should be animated on vertical shifts',
|
||||
testWidgets('should be animated on vertical shifts',
|
||||
(WidgetTester tester) async {
|
||||
const Offset verticalShift = Offset(0, 200);
|
||||
|
||||
@ -451,7 +449,7 @@ void main() {
|
||||
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 {
|
||||
const Offset verticalShift = Offset(0, 200);
|
||||
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
@ -143,6 +142,8 @@ void main() {
|
||||
|
||||
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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(material.elevation, equals(highlightElevation));
|
||||
await gesture2.up();
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking("MaterialButton's disabledColor takes precedence over its default disabled color.", (WidgetTester tester) async {
|
||||
@ -299,6 +302,8 @@ void main() {
|
||||
|
||||
await tester.pump();
|
||||
expect(focusNode.hasPrimaryFocus, isTrue);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('MaterialButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
|
||||
|
@ -6,8 +6,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
const Key key = Key('testContainer');
|
||||
const Color trueColor = Colors.red;
|
||||
|
@ -10,8 +10,7 @@ library;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/test_border.dart' show TestBorder;
|
||||
|
||||
class NotifyMaterial extends StatelessWidget {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
void onPressed(TestMenu item) {}
|
||||
@ -54,7 +53,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
|
@ -5,7 +5,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
|
||||
void main() {
|
||||
Finder findMenuPanels() {
|
||||
@ -43,7 +42,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
@ -86,7 +85,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
@ -129,7 +128,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
@ -172,7 +171,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
@ -238,7 +237,7 @@ void main() {
|
||||
expect(panelPadding.padding, equals(const EdgeInsets.all(20)));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('visual density', (WidgetTester tester) async {
|
||||
testWidgets('visual density', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
import 'package:flutter/material.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 onPressed(TestMenu item) {}
|
||||
@ -54,7 +54,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
@ -107,7 +107,8 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
enum RadiusType {
|
||||
Sharp,
|
||||
@ -80,7 +79,7 @@ void main() {
|
||||
expect(box.size.height, equals(0));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('MergeableMaterial update slice', (WidgetTester tester) async {
|
||||
testWidgets('MergeableMaterial update slice', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -234,7 +233,7 @@ void main() {
|
||||
debugDisableShadows = true;
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('MergeableMaterial skips shadow for zero elevation', (WidgetTester tester) async {
|
||||
testWidgets('MergeableMaterial skips shadow for zero elevation', (WidgetTester tester) async {
|
||||
debugDisableShadows = false;
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
@ -1168,7 +1167,7 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgetsWithLeakTracking('MergeableMaterial dividers', (WidgetTester tester) async {
|
||||
testWidgets('MergeableMaterial dividers', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
@ -1330,7 +1329,7 @@ void main() {
|
||||
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 materialSliceColor = Colors.green;
|
||||
|
||||
|
@ -13,8 +13,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Navigation bar updates destinations when tapped', (WidgetTester tester) async {
|
||||
|
@ -11,8 +11,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('copyWith, ==, hashCode basics', () {
|
||||
|
@ -5,10 +5,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Navigation drawer updates destinations when tapped',
|
||||
testWidgets('Navigation drawer updates destinations when tapped',
|
||||
(WidgetTester tester) async {
|
||||
int mutatedIndex = -1;
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
@ -51,7 +49,7 @@ void main() {
|
||||
expect(mutatedIndex, 0);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('NavigationDrawer can update background color',
|
||||
testWidgets('NavigationDrawer can update background color',
|
||||
(WidgetTester tester) async {
|
||||
const Color color = Colors.yellow;
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
@ -84,7 +82,7 @@ void main() {
|
||||
expect(_getMaterial(tester).color, equals(color));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('NavigationDrawer can update elevation',
|
||||
testWidgets('NavigationDrawer can update elevation',
|
||||
(WidgetTester tester) async {
|
||||
const double elevation = 42.0;
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
@ -116,7 +114,7 @@ void main() {
|
||||
expect(_getMaterial(tester).elevation, equals(elevation));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'NavigationDrawer uses proper defaults when no parameters are given',
|
||||
(WidgetTester tester) async {
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
@ -165,7 +163,7 @@ void main() {
|
||||
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>();
|
||||
widgetSetup(tester, 500, viewHeight: 300);
|
||||
await tester.pumpWidget(
|
||||
@ -212,7 +210,7 @@ void main() {
|
||||
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>();
|
||||
const double viewHeight = 300;
|
||||
widgetSetup(tester, 500, viewHeight: viewHeight);
|
||||
@ -253,7 +251,7 @@ void main() {
|
||||
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 ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
|
||||
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 ThemeData theme = ThemeData(useMaterial3: true);
|
||||
const Color color = Color(0xff0000ff);
|
||||
@ -374,7 +372,7 @@ void main() {
|
||||
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>();
|
||||
widgetSetup(tester, 3000, viewHeight: 3000);
|
||||
final Widget widget = _buildWidget(
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
@ -227,6 +226,8 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.primary.withOpacity(0.12)));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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');
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Default OutlinedButton meets a11y contrast guidelines', (WidgetTester tester) async {
|
||||
@ -360,6 +365,8 @@ void main() {
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
||||
|
||||
focusNode.dispose();
|
||||
},
|
||||
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(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
||||
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
||||
|
||||
focusNode.dispose();
|
||||
},
|
||||
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(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
||||
expect(textColor(), pressedColor);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
||||
expect(iconColor(), pressedColor);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
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 tester.pumpAndSettle();
|
||||
expect(outlinedButton, paints..drrect(color: pressedColor));
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('OutlinedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
|
||||
@ -727,6 +742,8 @@ void main() {
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasPrimaryFocus, isFalse);
|
||||
|
||||
focusNode.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('disabled and hovered OutlinedButton responds to mouse-exit', (WidgetTester tester) async {
|
||||
@ -818,6 +835,8 @@ void main() {
|
||||
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('When OutlinedButton disable, Can not set OutlinedButton focus.', (WidgetTester tester) async {
|
||||
@ -841,6 +860,8 @@ void main() {
|
||||
|
||||
expect(gotFocus, isFalse);
|
||||
expect(node.hasFocus, isFalse);
|
||||
|
||||
node.dispose();
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
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.
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
@ -1969,15 +1990,15 @@ void main() {
|
||||
await gesture.removePointer();
|
||||
}
|
||||
|
||||
testWidgetsWithLeakTracking('OutlinedButton statesController', (WidgetTester tester) async {
|
||||
testWidgets('OutlinedButton statesController', (WidgetTester tester) async {
|
||||
testStatesController(null, tester);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('OutlinedButton.icon statesController', (WidgetTester tester) async {
|
||||
testWidgets('OutlinedButton.icon statesController', (WidgetTester tester) async {
|
||||
testStatesController(const Icon(Icons.add), tester);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Disabled OutlinedButton statesController', (WidgetTester tester) async {
|
||||
testWidgets('Disabled OutlinedButton statesController', (WidgetTester tester) async {
|
||||
int count = 0;
|
||||
void valueChanged() {
|
||||
count += 1;
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('OutlinedButtonThemeData lerp special cases', () {
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
const Color kSelectedColor = Color(0xFF00FF00);
|
||||
const Color kUnselectedColor = Colors.transparent;
|
||||
@ -208,7 +207,7 @@ void main() {
|
||||
expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('PageSelector indicatorSize', (WidgetTester tester) async {
|
||||
testWidgets('PageSelector indicatorSize', (WidgetTester tester) async {
|
||||
final TabController tabController = TabController(
|
||||
vsync: const TestVSync(),
|
||||
initialIndex: 1,
|
||||
|
@ -7,8 +7,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Default PageTransitionsTheme platform', (WidgetTester tester) async {
|
||||
|
@ -5,8 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../foundation/leak_tracking.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
// Pumps and ensures that the BottomSheet animates non-linearly.
|
||||
@ -124,7 +123,7 @@ void main() {
|
||||
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(
|
||||
home: Scaffold(
|
||||
body: const Center(child: Text('body')),
|
||||
@ -187,7 +186,7 @@ void main() {
|
||||
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>();
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
@ -299,7 +298,7 @@ void main() {
|
||||
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(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -410,7 +409,7 @@ void main() {
|
||||
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>();
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
@ -590,7 +589,7 @@ void main() {
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/71435
|
||||
testWidgetsWithLeakTracking(
|
||||
testWidgets(
|
||||
'Scaffold.bottomSheet should be updated without creating a new RO'
|
||||
' when the new widget has the same key and type.',
|
||||
(WidgetTester tester) async {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user