mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Migrate yet even more widget framework tests to null safety. (#67941)
Migrate yet even more widget framework tests to null safety.
This commit is contained in:
parent
f5608f2b33
commit
f7ee440207
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -162,7 +160,7 @@ class MutatingRoute extends MaterialPageRoute<void> {
|
||||
}
|
||||
|
||||
class _SimpleStatefulWidget extends StatefulWidget {
|
||||
const _SimpleStatefulWidget({ Key key }) : super(key: key);
|
||||
const _SimpleStatefulWidget({ Key? key }) : super(key: key);
|
||||
@override
|
||||
_SimpleState createState() => _SimpleState();
|
||||
}
|
||||
@ -175,7 +173,7 @@ class _SimpleState extends State<_SimpleStatefulWidget> {
|
||||
}
|
||||
|
||||
class MyStatefulWidget extends StatefulWidget {
|
||||
const MyStatefulWidget({ Key key, this.value = '123' }) : super(key: key);
|
||||
const MyStatefulWidget({ Key? key, this.value = '123' }) : super(key: key);
|
||||
final String value;
|
||||
@override
|
||||
MyStatefulWidgetState createState() => MyStatefulWidgetState();
|
||||
@ -339,7 +337,7 @@ Future<void> main() async {
|
||||
),
|
||||
),
|
||||
);
|
||||
key.currentState.push(MaterialPageRoute<void>(
|
||||
key.currentState!.push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext c) {
|
||||
return Hero(
|
||||
tag: 'hero',
|
||||
@ -803,7 +801,7 @@ Future<void> main() async {
|
||||
const Key homeHeroKey = Key('home hero');
|
||||
const Key routeHeroKey = Key('route hero');
|
||||
bool routeIncludesHero = true;
|
||||
StateSetter heroCardSetState;
|
||||
late StateSetter heroCardSetState;
|
||||
|
||||
// Show a 200x200 Hero tagged 'H', with key routeHeroKey
|
||||
final MaterialPageRoute<void> route = MaterialPageRoute<void>(
|
||||
@ -1196,7 +1194,7 @@ Future<void> main() async {
|
||||
bool _isVisible(Element node) {
|
||||
bool isVisible = true;
|
||||
node.visitAncestorElements((Element ancestor) {
|
||||
final RenderObject r = ancestor.renderObject;
|
||||
final RenderObject r = ancestor.renderObject!;
|
||||
if (r is RenderOpacity && r.opacity == 0) {
|
||||
isVisible = false;
|
||||
return false;
|
||||
@ -1300,7 +1298,7 @@ Future<void> main() async {
|
||||
});
|
||||
|
||||
testWidgets('Hero createRectTween', (WidgetTester tester) async {
|
||||
RectTween createRectTween(Rect begin, Rect end) {
|
||||
RectTween createRectTween(Rect? begin, Rect? end) {
|
||||
return MaterialRectCenterArcTween(begin: begin, end: end);
|
||||
}
|
||||
|
||||
@ -1415,7 +1413,7 @@ Future<void> main() async {
|
||||
testWidgets('Hero createRectTween for Navigator that is not full screen', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/25272
|
||||
|
||||
RectTween createRectTween(Rect begin, Rect end) {
|
||||
RectTween createRectTween(Rect? begin, Rect? end) {
|
||||
return RectTween(begin: begin, end: end);
|
||||
}
|
||||
|
||||
@ -1485,17 +1483,17 @@ Future<void> main() async {
|
||||
|
||||
await tester.pump(duration * 0.25);
|
||||
Rect actualHeroRect = tester.getRect(find.byKey(secondKey));
|
||||
Rect predictedHeroRect = pushRectTween.lerp(curve.transform(0.25));
|
||||
Rect predictedHeroRect = pushRectTween.lerp(curve.transform(0.25))!;
|
||||
expect(actualHeroRect, within<Rect>(distance: epsilon, from: predictedHeroRect));
|
||||
|
||||
await tester.pump(duration * 0.25);
|
||||
actualHeroRect = tester.getRect(find.byKey(secondKey));
|
||||
predictedHeroRect = pushRectTween.lerp(curve.transform(0.5));
|
||||
predictedHeroRect = pushRectTween.lerp(curve.transform(0.5))!;
|
||||
expect(actualHeroRect, within<Rect>(distance: epsilon, from: predictedHeroRect));
|
||||
|
||||
await tester.pump(duration * 0.25);
|
||||
actualHeroRect = tester.getRect(find.byKey(secondKey));
|
||||
predictedHeroRect = pushRectTween.lerp(curve.transform(0.75));
|
||||
predictedHeroRect = pushRectTween.lerp(curve.transform(0.75))!;
|
||||
expect(actualHeroRect, within<Rect>(distance: epsilon, from: predictedHeroRect));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
@ -1516,17 +1514,17 @@ Future<void> main() async {
|
||||
|
||||
await tester.pump(duration * 0.25);
|
||||
actualHeroRect = tester.getRect(find.byKey(firstKey));
|
||||
predictedHeroRect = popRectTween.lerp(curve.transform(0.25));
|
||||
predictedHeroRect = popRectTween.lerp(curve.transform(0.25))!;
|
||||
expect(actualHeroRect, within<Rect>(distance: epsilon, from: predictedHeroRect));
|
||||
|
||||
await tester.pump(duration * 0.25);
|
||||
actualHeroRect = tester.getRect(find.byKey(firstKey));
|
||||
predictedHeroRect = popRectTween.lerp(curve.transform(0.5));
|
||||
predictedHeroRect = popRectTween.lerp(curve.transform(0.5))!;
|
||||
expect(actualHeroRect, within<Rect>(distance: epsilon, from: predictedHeroRect));
|
||||
|
||||
await tester.pump(duration * 0.25);
|
||||
actualHeroRect = tester.getRect(find.byKey(firstKey));
|
||||
predictedHeroRect = popRectTween.lerp(curve.transform(0.75));
|
||||
predictedHeroRect = popRectTween.lerp(curve.transform(0.75))!;
|
||||
expect(actualHeroRect, within<Rect>(distance: epsilon, from: predictedHeroRect));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
@ -1876,7 +1874,7 @@ Future<void> main() async {
|
||||
),
|
||||
);
|
||||
|
||||
nestedNavigator.currentState.push(MaterialPageRoute<void>(
|
||||
nestedNavigator.currentState!.push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return Hero(
|
||||
tag: heroTag,
|
||||
@ -1893,7 +1891,7 @@ Future<void> main() async {
|
||||
expect(find.byKey(nestedRouteHeroBottom), findsNothing);
|
||||
expect(find.byKey(nestedRouteHeroBottom, skipOffstage: false), findsOneWidget);
|
||||
|
||||
rootNavigator.currentState.push(MaterialPageRoute<void>(
|
||||
rootNavigator.currentState!.push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return const Text('Foo');
|
||||
},
|
||||
@ -1910,7 +1908,7 @@ Future<void> main() async {
|
||||
// Doesn't crash.
|
||||
expect(tester.takeException(), isNull);
|
||||
|
||||
rootNavigator.currentState.pop();
|
||||
rootNavigator.currentState!.pop();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Foo'), findsNothing);
|
||||
@ -1951,7 +1949,7 @@ Future<void> main() async {
|
||||
expect(find.byKey(largeContainer), isInCard);
|
||||
expect(find.byKey(smallContainer, skipOffstage: false), findsNothing);
|
||||
|
||||
rootNavigator.currentState.push(
|
||||
rootNavigator.currentState!.push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return Center(
|
||||
@ -2120,7 +2118,7 @@ Future<void> main() async {
|
||||
expect(find.byKey(largeContainer), isInCard);
|
||||
expect(find.byKey(smallContainer, skipOffstage: false), findsNothing);
|
||||
|
||||
navigator.currentState.pushReplacement(
|
||||
navigator.currentState!.pushReplacement(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return Center(
|
||||
@ -2214,7 +2212,7 @@ Future<void> main() async {
|
||||
}
|
||||
);
|
||||
|
||||
navigatorKey.currentState.push(route2);
|
||||
navigatorKey.currentState!.push(route2);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(shuttlesBuilt, 1);
|
||||
@ -2281,10 +2279,10 @@ Future<void> main() async {
|
||||
}
|
||||
);
|
||||
|
||||
final _SimpleState state1 = key1.currentState;
|
||||
final _SimpleState state1 = key1.currentState!;
|
||||
state1.state = 1;
|
||||
|
||||
navigatorKey.currentState.push(route2);
|
||||
navigatorKey.currentState!.push(route2);
|
||||
await tester.pump();
|
||||
|
||||
expect(state1.mounted, isTrue);
|
||||
@ -2294,7 +2292,7 @@ Future<void> main() async {
|
||||
// The element should be mounted and unique.
|
||||
expect(state1.mounted, isTrue);
|
||||
|
||||
navigatorKey.currentState.pop();
|
||||
navigatorKey.currentState!.pop();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// State is preserved.
|
||||
@ -2366,7 +2364,7 @@ Future<void> main() async {
|
||||
// Before push image1 should be laid out correctly.
|
||||
expect(renderImage.size, const Size(100, 100));
|
||||
|
||||
navigatorKey.currentState.push(route2);
|
||||
navigatorKey.currentState!.push(route2);
|
||||
await tester.pump();
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(const Offset(0.01, 300));
|
||||
@ -2425,7 +2423,7 @@ Future<void> main() async {
|
||||
'In a pop transition, when fromHero is null, the to hero should eventually become visible',
|
||||
(WidgetTester tester) async {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
|
||||
StateSetter setState;
|
||||
late StateSetter setState;
|
||||
bool shouldDisplayHero = true;
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2452,7 +2450,7 @@ Future<void> main() async {
|
||||
},
|
||||
);
|
||||
|
||||
navigatorKey.currentState.push(route2);
|
||||
navigatorKey.currentState!.push(route2);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('text'), findsOneWidget);
|
||||
@ -2463,7 +2461,7 @@ Future<void> main() async {
|
||||
|
||||
expect(find.text('text'), findsNothing);
|
||||
|
||||
navigatorKey.currentState.pop();
|
||||
navigatorKey.currentState!.pop();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(Placeholder), findsOneWidget);
|
||||
@ -2475,7 +2473,7 @@ Future<void> main() async {
|
||||
final Key container2 = UniqueKey();
|
||||
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
|
||||
|
||||
final Animatable<Size> tween = SizeTween(
|
||||
final Animatable<Size?> tween = SizeTween(
|
||||
begin: const Size(200, 200),
|
||||
end: const Size(100, 100),
|
||||
).chain(CurveTween(curve: Curves.fastOutSlowIn));
|
||||
@ -2488,7 +2486,7 @@ Future<void> main() async {
|
||||
body: Center(
|
||||
child: Hero(
|
||||
tag: 'test',
|
||||
createRectTween: (Rect begin, Rect end) {
|
||||
createRectTween: (Rect? begin, Rect? end) {
|
||||
return RectTween(begin: begin, end: end);
|
||||
},
|
||||
child: Container(
|
||||
@ -2504,12 +2502,12 @@ Future<void> main() async {
|
||||
final Size originalSize = tester.getSize(find.byKey(container1));
|
||||
expect(originalSize, const Size(100, 100));
|
||||
|
||||
navigator.currentState.push(MaterialPageRoute<void>(builder: (BuildContext context) {
|
||||
navigator.currentState!.push(MaterialPageRoute<void>(builder: (BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Hero(
|
||||
tag: 'test',
|
||||
createRectTween: (Rect begin, Rect end) {
|
||||
createRectTween: (Rect? begin, Rect? end) {
|
||||
return RectTween(begin: begin, end: end);
|
||||
},
|
||||
child: Container(
|
||||
@ -2525,7 +2523,7 @@ Future<void> main() async {
|
||||
final Size newSize = tester.getSize(find.byKey(container2));
|
||||
expect(newSize, const Size(200, 200));
|
||||
|
||||
navigator.currentState.pop();
|
||||
navigator.currentState!.pop();
|
||||
await tester.pump();
|
||||
|
||||
// Jump 25% into the transition (total length = 300ms)
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
@TestOn('chrome')
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -12,11 +10,11 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
void main() {
|
||||
test('IconDataDiagnosticsProperty includes valueProperties in JSON', () {
|
||||
IconDataProperty property = IconDataProperty('foo', const IconData(101010));
|
||||
final Map<String, Object> valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties'] as Map<String, Object>;
|
||||
final Map<String, Object> valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties']! as Map<String, Object>;
|
||||
expect(valueProperties['codePoint'], 101010);
|
||||
|
||||
property = IconDataProperty('foo', null);
|
||||
final Map<String, Object> json = property.toJsonMap(const DiagnosticsSerializationDelegate());
|
||||
final Map<String, Object?> json = property.toJsonMap(const DiagnosticsSerializationDelegate());
|
||||
expect(json.containsKey('valueProperties'), isFalse);
|
||||
});
|
||||
}
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -25,7 +23,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
final RichText text = tester.widget(find.byType(RichText));
|
||||
expect(text.text.style.color, const Color(0xFF666666).withOpacity(0.5));
|
||||
expect(text.text.style!.color, const Color(0xFF666666).withOpacity(0.5));
|
||||
});
|
||||
|
||||
testWidgets('Icon sizing - no theme, default size', (WidgetTester tester) async {
|
||||
@ -125,7 +123,7 @@ void main() {
|
||||
);
|
||||
|
||||
final RichText richText = tester.firstWidget(find.byType(RichText));
|
||||
expect(richText.text.style.fontFamily, equals('Roboto'));
|
||||
expect(richText.text.style!.fontFamily, equals('Roboto'));
|
||||
});
|
||||
|
||||
testWidgets('Icon with semantic label', (WidgetTester tester) async {
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
@ -78,8 +76,7 @@ void main() {
|
||||
|
||||
await pumpWithSigma(5.0);
|
||||
final RenderObject renderObject = tester.firstRenderObject(find.byType(ImageFiltered));
|
||||
final ImageFilterLayer originalLayer = renderObject.debugLayer as ImageFilterLayer;
|
||||
expect(originalLayer, isNotNull);
|
||||
final ImageFilterLayer originalLayer = renderObject.debugLayer! as ImageFilterLayer;
|
||||
|
||||
// Change blur sigma to force a repaint.
|
||||
await pumpWithSigma(10.0);
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
@ -25,7 +23,7 @@ void main() {
|
||||
|
||||
expect(MockHttpHeaders.headers['flutter'], <String>['flutter']);
|
||||
|
||||
}, createHttpClient: (SecurityContext _) {
|
||||
}, createHttpClient: (SecurityContext? _) {
|
||||
return client;
|
||||
});
|
||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/57187
|
||||
@ -62,7 +60,7 @@ class MockHttpClientResponse extends Fake implements HttpClientResponse {
|
||||
HttpClientResponseCompressionState get compressionState => HttpClientResponseCompressionState.decompressed;
|
||||
|
||||
@override
|
||||
StreamSubscription<List<int>> listen(void Function(List<int> event) onData, {Function onError, void Function() onDone, bool cancelOnError}) {
|
||||
StreamSubscription<List<int>> listen(void Function(List<int> event)? onData, {Function? onError, void Function()? onDone, bool? cancelOnError}) {
|
||||
return Stream<List<int>>.fromIterable(<List<int>>[kTransparentImage]).listen(
|
||||
onData,
|
||||
onDone: onDone,
|
||||
@ -78,6 +76,6 @@ class MockHttpHeaders extends Fake implements HttpHeaders {
|
||||
@override
|
||||
void add(String key, Object value, { bool preserveHeaderCase = false }) {
|
||||
headers[key] ??= <String>[];
|
||||
headers[key].add(value.toString());
|
||||
headers[key]!.add(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -12,7 +10,7 @@ import '../painting/mocks_for_image_cache.dart';
|
||||
|
||||
|
||||
void main() {
|
||||
ImageProvider _image;
|
||||
late ImageProvider _image;
|
||||
|
||||
setUpAll(() async {
|
||||
_image = TestImageProvider(
|
||||
@ -45,8 +43,7 @@ void main() {
|
||||
);
|
||||
|
||||
final Image image = tester.widget(find.byType(Image));
|
||||
expect(image, isNotNull);
|
||||
expect(image.color.alpha, equals(128));
|
||||
expect(image.color!.alpha, equals(128));
|
||||
});
|
||||
|
||||
testWidgets('ImageIcon sizing - no theme, explicit size', (WidgetTester tester) async {
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
@TestOn('!chrome') // asset bundle behaves differently.
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui' as ui show Image;
|
||||
@ -43,7 +41,7 @@ class TestAssetBundle extends CachingAssetBundle {
|
||||
|
||||
@override
|
||||
Future<ByteData> load(String key) {
|
||||
ByteData data;
|
||||
late ByteData data;
|
||||
switch (key) {
|
||||
case 'assets/image.png':
|
||||
data = TestByteData(1.0);
|
||||
@ -71,7 +69,7 @@ class TestAssetBundle extends CachingAssetBundle {
|
||||
Future<String> loadString(String key, { bool cache = true }) {
|
||||
if (key == 'AssetManifest.json')
|
||||
return SynchronousFuture<String>(manifest);
|
||||
return SynchronousFuture<String>(null);
|
||||
return SynchronousFuture<String>('');
|
||||
}
|
||||
|
||||
@override
|
||||
@ -91,21 +89,20 @@ class TestAssetImage extends AssetImage {
|
||||
|
||||
@override
|
||||
ImageStreamCompleter load(AssetBundleImageKey key, DecoderCallback decode) {
|
||||
ImageInfo imageInfo;
|
||||
late ImageInfo imageInfo;
|
||||
key.bundle.load(key.name).then<void>((ByteData data) {
|
||||
final TestByteData testData = data as TestByteData;
|
||||
final ui.Image image = images[testData.scale];
|
||||
final ui.Image image = images[testData.scale]!;
|
||||
assert(image != null, 'Expected ${testData.scale} to have a key in $images');
|
||||
imageInfo = ImageInfo(image: image, scale: key.scale);
|
||||
});
|
||||
assert(imageInfo != null);
|
||||
return FakeImageStreamCompleter(
|
||||
SynchronousFuture<ImageInfo>(imageInfo)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildImageAtRatio(String imageName, Key key, double ratio, bool inferSize, Map<double, ui.Image> images, [ AssetBundle bundle ]) {
|
||||
Widget buildImageAtRatio(String imageName, Key key, double ratio, bool inferSize, Map<double, ui.Image> images, [ AssetBundle? bundle ]) {
|
||||
const double windowSize = 500.0; // 500 logical pixels
|
||||
const double imageSize = 200.0; // 200 logical pixels
|
||||
|
||||
@ -313,12 +310,12 @@ void main() {
|
||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images, bundle));
|
||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||
// Verify we got the 10x scaled image, since the TestByteData said it should be 10x.
|
||||
expect(getRenderImage(tester, key).image.height, 480);
|
||||
expect(getRenderImage(tester, key).image!.height, 480);
|
||||
key = GlobalKey();
|
||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images, bundle));
|
||||
expect(getRenderImage(tester, key).size, const Size(480.0, 480.0));
|
||||
// Verify we got the 10x scaled image, since the TestByteData said it should be 10x.
|
||||
expect(getRenderImage(tester, key).image.height, 480);
|
||||
expect(getRenderImage(tester, key).image!.height, 480);
|
||||
});
|
||||
|
||||
testWidgets('Image cache resize upscale display 5', (WidgetTester tester) async {
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:ui' as ui show Image;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -31,7 +29,7 @@ class TestImageProvider extends ImageProvider<TestImageProvider> {
|
||||
}
|
||||
|
||||
void main() {
|
||||
ui.Image testImage;
|
||||
late ui.Image testImage;
|
||||
setUpAll(() async {
|
||||
testImage = await createTestImage(width: 16, height: 9);
|
||||
});
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:typed_data';
|
||||
@ -19,18 +17,18 @@ import '../image_data.dart';
|
||||
import 'semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
int originalCacheSize;
|
||||
ui.Image image10x10;
|
||||
late int originalCacheSize;
|
||||
late ui.Image image10x10;
|
||||
|
||||
setUp(() async {
|
||||
originalCacheSize = imageCache.maximumSize;
|
||||
imageCache.clear();
|
||||
imageCache.clearLiveImages();
|
||||
originalCacheSize = imageCache!.maximumSize;
|
||||
imageCache!.clear();
|
||||
imageCache!.clearLiveImages();
|
||||
image10x10 = await createTestImage(width: 10, height: 10);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
imageCache.maximumSize = originalCacheSize;
|
||||
imageCache!.maximumSize = originalCacheSize;
|
||||
});
|
||||
|
||||
testWidgets('Verify Image resets its RenderImage when changing providers', (WidgetTester tester) async {
|
||||
@ -47,14 +45,14 @@ void main() {
|
||||
null,
|
||||
EnginePhase.layout,
|
||||
);
|
||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
RenderImage renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
|
||||
imageProvider1.complete(image10x10);
|
||||
await tester.idle(); // resolve the future from the image provider
|
||||
await tester.pump(null, EnginePhase.layout);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
|
||||
final TestImageProvider imageProvider2 = TestImageProvider();
|
||||
@ -70,7 +68,7 @@ void main() {
|
||||
EnginePhase.layout,
|
||||
);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
});
|
||||
|
||||
@ -89,14 +87,14 @@ void main() {
|
||||
null,
|
||||
EnginePhase.layout,
|
||||
);
|
||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
RenderImage renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
|
||||
imageProvider1.complete(image10x10);
|
||||
await tester.idle(); // resolve the future from the image provider
|
||||
await tester.pump(null, EnginePhase.layout);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
|
||||
final TestImageProvider imageProvider2 = TestImageProvider();
|
||||
@ -113,7 +111,7 @@ void main() {
|
||||
EnginePhase.layout,
|
||||
);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
});
|
||||
|
||||
@ -129,14 +127,14 @@ void main() {
|
||||
null,
|
||||
EnginePhase.layout,
|
||||
);
|
||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
RenderImage renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
|
||||
imageProvider1.complete(image10x10);
|
||||
await tester.idle(); // resolve the future from the image provider
|
||||
await tester.pump(null, EnginePhase.layout);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
|
||||
final TestImageProvider imageProvider2 = TestImageProvider();
|
||||
@ -150,7 +148,7 @@ void main() {
|
||||
EnginePhase.layout,
|
||||
);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
});
|
||||
|
||||
@ -167,14 +165,14 @@ void main() {
|
||||
null,
|
||||
EnginePhase.layout,
|
||||
);
|
||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
RenderImage renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
|
||||
imageProvider1.complete(image10x10);
|
||||
await tester.idle(); // resolve the future from the image provider
|
||||
await tester.pump(null, EnginePhase.layout);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
|
||||
final TestImageProvider imageProvider2 = TestImageProvider();
|
||||
@ -189,7 +187,7 @@ void main() {
|
||||
EnginePhase.layout,
|
||||
);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
});
|
||||
|
||||
@ -460,7 +458,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Verify Image stops listening to ImageStream', (WidgetTester tester) async {
|
||||
final ui.Image image100x100 = await tester.runAsync(() async => createTestImage(width: 100, height: 100));
|
||||
final ui.Image image100x100 = (await tester.runAsync(() async => createTestImage(width: 100, height: 100)))!;
|
||||
// Web does not override the toString, whereas VM does
|
||||
final String imageString = image100x100.toString();
|
||||
|
||||
@ -477,9 +475,9 @@ void main() {
|
||||
|
||||
testWidgets('Stream completer errors can be listened to by attaching before resolving', (WidgetTester tester) async {
|
||||
dynamic capturedException;
|
||||
StackTrace capturedStackTrace;
|
||||
ImageInfo capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
StackTrace? capturedStackTrace;
|
||||
ImageInfo? capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
capturedException = exception;
|
||||
capturedStackTrace = stackTrace;
|
||||
};
|
||||
@ -491,7 +489,7 @@ void main() {
|
||||
final StackTrace testStack = StackTrace.current;
|
||||
final TestImageProvider imageProvider = TestImageProvider();
|
||||
imageProvider._streamCompleter.addListener(ImageStreamListener(listener, onError: errorListener));
|
||||
ImageConfiguration configuration;
|
||||
late ImageConfiguration configuration;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -517,11 +515,11 @@ void main() {
|
||||
|
||||
testWidgets('Stream completer errors can be listened to by attaching after resolving', (WidgetTester tester) async {
|
||||
dynamic capturedException;
|
||||
StackTrace capturedStackTrace;
|
||||
StackTrace? capturedStackTrace;
|
||||
dynamic reportedException;
|
||||
StackTrace reportedStackTrace;
|
||||
ImageInfo capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
StackTrace? reportedStackTrace;
|
||||
ImageInfo? capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
capturedException = exception;
|
||||
capturedStackTrace = stackTrace;
|
||||
};
|
||||
@ -536,7 +534,7 @@ void main() {
|
||||
final Exception testException = Exception('cannot resolve host');
|
||||
final StackTrace testStack = StackTrace.current;
|
||||
final TestImageProvider imageProvider = TestImageProvider();
|
||||
ImageConfiguration configuration;
|
||||
late ImageConfiguration configuration;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -568,9 +566,9 @@ void main() {
|
||||
|
||||
testWidgets('Duplicate listener registration does not affect error listeners', (WidgetTester tester) async {
|
||||
dynamic capturedException;
|
||||
StackTrace capturedStackTrace;
|
||||
ImageInfo capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
StackTrace? capturedStackTrace;
|
||||
ImageInfo? capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
capturedException = exception;
|
||||
capturedStackTrace = stackTrace;
|
||||
};
|
||||
@ -584,7 +582,7 @@ void main() {
|
||||
imageProvider._streamCompleter.addListener(ImageStreamListener(listener, onError: errorListener));
|
||||
// Add the exact same listener a second time without the errorListener.
|
||||
imageProvider._streamCompleter.addListener(ImageStreamListener(listener));
|
||||
ImageConfiguration configuration;
|
||||
late ImageConfiguration configuration;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -610,10 +608,10 @@ void main() {
|
||||
|
||||
testWidgets('Duplicate error listeners are all called', (WidgetTester tester) async {
|
||||
dynamic capturedException;
|
||||
StackTrace capturedStackTrace;
|
||||
ImageInfo capturedImage;
|
||||
StackTrace? capturedStackTrace;
|
||||
ImageInfo? capturedImage;
|
||||
int errorListenerCalled = 0;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
capturedException = exception;
|
||||
capturedStackTrace = stackTrace;
|
||||
errorListenerCalled++;
|
||||
@ -628,7 +626,7 @@ void main() {
|
||||
imageProvider._streamCompleter.addListener(ImageStreamListener(listener, onError: errorListener));
|
||||
// Add the exact same errorListener a second time.
|
||||
imageProvider._streamCompleter.addListener(ImageStreamListener(listener, onError: errorListener));
|
||||
ImageConfiguration configuration;
|
||||
late ImageConfiguration configuration;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -656,9 +654,9 @@ void main() {
|
||||
testWidgets('Listeners are only removed if callback tuple matches', (WidgetTester tester) async {
|
||||
bool errorListenerCalled = false;
|
||||
dynamic reportedException;
|
||||
StackTrace reportedStackTrace;
|
||||
ImageInfo capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
StackTrace? reportedStackTrace;
|
||||
ImageInfo? capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
errorListenerCalled = true;
|
||||
reportedException = exception;
|
||||
reportedStackTrace = stackTrace;
|
||||
@ -674,7 +672,7 @@ void main() {
|
||||
// Now remove the listener the error listener is attached to.
|
||||
// Don't explicitly remove the error listener.
|
||||
imageProvider._streamCompleter.removeListener(ImageStreamListener(listener));
|
||||
ImageConfiguration configuration;
|
||||
late ImageConfiguration configuration;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -699,8 +697,8 @@ void main() {
|
||||
|
||||
testWidgets('Removing listener removes one listener and error listener', (WidgetTester tester) async {
|
||||
int errorListenerCalled = 0;
|
||||
ImageInfo capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
ImageInfo? capturedImage;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
errorListenerCalled++;
|
||||
};
|
||||
final ImageListener listener = (ImageInfo info, bool synchronous) {
|
||||
@ -716,7 +714,7 @@ void main() {
|
||||
// Now remove one entry of the specified listener and associated error listener.
|
||||
// Don't explicitly remove the error listener.
|
||||
imageProvider._streamCompleter.removeListener(ImageStreamListener(listener, onError: errorListener));
|
||||
ImageConfiguration configuration;
|
||||
late ImageConfiguration configuration;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -757,7 +755,7 @@ void main() {
|
||||
|
||||
testWidgets('Precache', (WidgetTester tester) async {
|
||||
final TestImageProvider provider = TestImageProvider();
|
||||
Future<void> precache;
|
||||
late Future<void> precache;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -772,7 +770,7 @@ void main() {
|
||||
|
||||
// Check that a second resolve of the same image is synchronous.
|
||||
final ImageStream stream = provider.resolve(provider._lastResolvedConfiguration);
|
||||
bool isSync;
|
||||
late bool isSync;
|
||||
stream.addListener(ImageStreamListener((ImageInfo image, bool sync) { isSync = sync; }));
|
||||
expect(isSync, isTrue);
|
||||
});
|
||||
@ -795,18 +793,19 @@ void main() {
|
||||
expect(listeners.length, 2);
|
||||
|
||||
// Make sure the first listener can be called re-entrantly
|
||||
listeners[1].onImage(null, false);
|
||||
listeners[1].onImage(null, false);
|
||||
final ImageInfo imageInfo = ImageInfo(image: image10x10);
|
||||
listeners[1].onImage(imageInfo.clone(), false);
|
||||
listeners[1].onImage(imageInfo.clone(), false);
|
||||
|
||||
// Make sure the second listener can be called re-entrantly.
|
||||
listeners[0].onImage(null, false);
|
||||
listeners[0].onImage(null, false);
|
||||
listeners[0].onImage(imageInfo.clone(), false);
|
||||
listeners[0].onImage(imageInfo.clone(), false);
|
||||
});
|
||||
|
||||
testWidgets('Precache completes with onError on error', (WidgetTester tester) async {
|
||||
dynamic capturedException;
|
||||
StackTrace capturedStackTrace;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace stackTrace) {
|
||||
StackTrace? capturedStackTrace;
|
||||
final ImageErrorListener errorListener = (dynamic exception, StackTrace? stackTrace) {
|
||||
capturedException = exception;
|
||||
capturedStackTrace = stackTrace;
|
||||
};
|
||||
@ -814,7 +813,7 @@ void main() {
|
||||
final Exception testException = Exception('cannot resolve host');
|
||||
final StackTrace testStack = StackTrace.current;
|
||||
final TestImageProvider imageProvider = TestImageProvider();
|
||||
Future<void> precache;
|
||||
late Future<void> precache;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -860,7 +859,7 @@ void main() {
|
||||
|
||||
final TestImageProvider imageProvider1 = TestImageProvider();
|
||||
final TestImageProvider imageProvider2 = TestImageProvider();
|
||||
final ui.Image image100x100 = await tester.runAsync(() async => createTestImage(width: 100, height: 100));
|
||||
final ui.Image image100x100 = (await tester.runAsync(() async => createTestImage(width: 100, height: 100)))!;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Container(
|
||||
@ -873,7 +872,7 @@ void main() {
|
||||
null,
|
||||
EnginePhase.layout,
|
||||
);
|
||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
RenderImage renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNull);
|
||||
|
||||
imageProvider1.complete(image10x10);
|
||||
@ -881,10 +880,10 @@ void main() {
|
||||
await tester.idle(); // resolve the future from the image provider
|
||||
await tester.pump(null, EnginePhase.layout);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
|
||||
final ui.Image oldImage = renderImage.image;
|
||||
final ui.Image oldImage = renderImage.image!;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Container(
|
||||
@ -898,7 +897,7 @@ void main() {
|
||||
EnginePhase.layout,
|
||||
);
|
||||
|
||||
renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||
renderImage = key.currentContext!.findRenderObject()! as RenderImage;
|
||||
expect(renderImage.image, isNotNull);
|
||||
expect(renderImage.image, isNot(equals(oldImage)));
|
||||
});
|
||||
@ -974,23 +973,23 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Image invokes frameBuilder with correct frameNumber argument', (WidgetTester tester) async {
|
||||
final ui.Codec codec = await tester.runAsync(() {
|
||||
final ui.Codec codec = (await tester.runAsync(() {
|
||||
return ui.instantiateImageCodec(Uint8List.fromList(kAnimatedGif));
|
||||
});
|
||||
}))!;
|
||||
|
||||
Future<ui.Image> nextFrame() async {
|
||||
final ui.FrameInfo frameInfo = await tester.runAsync(codec.getNextFrame);
|
||||
final ui.FrameInfo frameInfo = (await tester.runAsync(codec.getNextFrame))!;
|
||||
return frameInfo.image;
|
||||
}
|
||||
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||
int lastFrame;
|
||||
int? lastFrame;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
lastFrame = frame;
|
||||
return Center(child: child);
|
||||
},
|
||||
@ -1015,13 +1014,13 @@ void main() {
|
||||
testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=false', (WidgetTester tester) async {
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||
int lastFrame;
|
||||
bool lastFrameWasSync;
|
||||
int? lastFrame;
|
||||
late bool lastFrameWasSync;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
lastFrame = frame;
|
||||
lastFrameWasSync = wasSynchronouslyLoaded;
|
||||
return child;
|
||||
@ -1041,13 +1040,13 @@ void main() {
|
||||
testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=true', (WidgetTester tester) async {
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter(ImageInfo(image: image10x10.clone()));
|
||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||
int lastFrame;
|
||||
bool lastFrameWasSync;
|
||||
int? lastFrame;
|
||||
late bool lastFrameWasSync;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
lastFrame = frame;
|
||||
lastFrameWasSync = wasSynchronouslyLoaded;
|
||||
return child;
|
||||
@ -1071,7 +1070,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
return Center(child: child);
|
||||
},
|
||||
),
|
||||
@ -1084,7 +1083,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
return Padding(padding: const EdgeInsets.all(1), child: child);
|
||||
},
|
||||
),
|
||||
@ -1097,21 +1096,21 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Image state handles enabling and disabling of tickers', (WidgetTester tester) async {
|
||||
final ui.Codec codec = await tester.runAsync(() {
|
||||
final ui.Codec codec = (await tester.runAsync(() {
|
||||
return ui.instantiateImageCodec(Uint8List.fromList(kAnimatedGif));
|
||||
});
|
||||
}))!;
|
||||
|
||||
Future<ui.Image> nextFrame() async {
|
||||
final ui.FrameInfo frameInfo = await tester.runAsync(codec.getNextFrame);
|
||||
final ui.FrameInfo frameInfo = (await tester.runAsync(codec.getNextFrame))!;
|
||||
return frameInfo.image;
|
||||
}
|
||||
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||
int lastFrame;
|
||||
int? lastFrame;
|
||||
int buildCount = 0;
|
||||
|
||||
Widget buildFrame(BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
Widget buildFrame(BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
lastFrame = frame;
|
||||
buildCount++;
|
||||
return child;
|
||||
@ -1172,12 +1171,12 @@ void main() {
|
||||
testWidgets('Image invokes loadingBuilder on chunk event notification', (WidgetTester tester) async {
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
|
||||
final List<ImageChunkEvent?> chunkEvents = <ImageChunkEvent?>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
chunkEvents.add(loadingProgress);
|
||||
if (loadingProgress == null)
|
||||
return child;
|
||||
@ -1241,10 +1240,10 @@ void main() {
|
||||
Image(
|
||||
image: imageProvider,
|
||||
excludeFromSemantics: true,
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
return Padding(padding: const EdgeInsets.all(1), child: child);
|
||||
},
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
return Center(child: child);
|
||||
},
|
||||
),
|
||||
@ -1279,7 +1278,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
return Center(child: child);
|
||||
},
|
||||
),
|
||||
@ -1302,7 +1301,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: imageProvider,
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
return Center(child: child);
|
||||
},
|
||||
),
|
||||
@ -1444,14 +1443,14 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Same image provider in multiple parts of the tree, no cache room left', (WidgetTester tester) async {
|
||||
imageCache.maximumSize = 0;
|
||||
imageCache!.maximumSize = 0;
|
||||
|
||||
final TestImageProvider provider1 = TestImageProvider();
|
||||
final TestImageProvider provider2 = TestImageProvider();
|
||||
|
||||
expect(provider1.loadCallCount, 0);
|
||||
expect(provider2.loadCallCount, 0);
|
||||
expect(imageCache.liveImageCount, 0);
|
||||
expect(imageCache!.liveImageCount, 0);
|
||||
|
||||
await tester.pumpWidget(Column(
|
||||
children: <Widget>[
|
||||
@ -1463,13 +1462,13 @@ void main() {
|
||||
],
|
||||
));
|
||||
|
||||
expect(imageCache.liveImageCount, 2);
|
||||
expect(imageCache.statusForKey(provider1).live, true);
|
||||
expect(imageCache.statusForKey(provider1).pending, false);
|
||||
expect(imageCache.statusForKey(provider1).keepAlive, false);
|
||||
expect(imageCache.statusForKey(provider2).live, true);
|
||||
expect(imageCache.statusForKey(provider2).pending, false);
|
||||
expect(imageCache.statusForKey(provider2).keepAlive, false);
|
||||
expect(imageCache!.liveImageCount, 2);
|
||||
expect(imageCache!.statusForKey(provider1).live, true);
|
||||
expect(imageCache!.statusForKey(provider1).pending, false);
|
||||
expect(imageCache!.statusForKey(provider1).keepAlive, false);
|
||||
expect(imageCache!.statusForKey(provider2).live, true);
|
||||
expect(imageCache!.statusForKey(provider2).pending, false);
|
||||
expect(imageCache!.statusForKey(provider2).keepAlive, false);
|
||||
|
||||
expect(provider1.loadCallCount, 1);
|
||||
expect(provider2.loadCallCount, 1);
|
||||
@ -1480,28 +1479,28 @@ void main() {
|
||||
provider2.complete(image10x10.clone());
|
||||
await tester.idle();
|
||||
|
||||
expect(imageCache.liveImageCount, 2);
|
||||
expect(imageCache.currentSize, 0);
|
||||
expect(imageCache!.liveImageCount, 2);
|
||||
expect(imageCache!.currentSize, 0);
|
||||
|
||||
await tester.pumpWidget(Image(image: provider2));
|
||||
await tester.idle();
|
||||
expect(imageCache.statusForKey(provider1).untracked, true);
|
||||
expect(imageCache.statusForKey(provider2).live, true);
|
||||
expect(imageCache.statusForKey(provider2).pending, false);
|
||||
expect(imageCache.statusForKey(provider2).keepAlive, false);
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache!.statusForKey(provider1).untracked, true);
|
||||
expect(imageCache!.statusForKey(provider2).live, true);
|
||||
expect(imageCache!.statusForKey(provider2).pending, false);
|
||||
expect(imageCache!.statusForKey(provider2).keepAlive, false);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
|
||||
await tester.pumpWidget(const SizedBox());
|
||||
await tester.idle();
|
||||
expect(provider1.loadCallCount, 1);
|
||||
expect(provider2.loadCallCount, 1);
|
||||
expect(imageCache.liveImageCount, 0);
|
||||
expect(imageCache!.liveImageCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('precacheImage does not hold weak ref for more than a frame', (WidgetTester tester) async {
|
||||
imageCache.maximumSize = 0;
|
||||
imageCache!.maximumSize = 0;
|
||||
final TestImageProvider provider = TestImageProvider();
|
||||
Future<void> precache;
|
||||
late Future<void> precache;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -1514,8 +1513,8 @@ void main() {
|
||||
await precache;
|
||||
|
||||
// Should have ended up with only a weak ref, not in cache because cache size is 0
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache.containsKey(provider), false);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
expect(imageCache!.containsKey(provider), false);
|
||||
|
||||
final ImageCacheStatus providerLocation = await provider.obtainCacheStatus(configuration: ImageConfiguration.empty);
|
||||
|
||||
@ -1527,31 +1526,31 @@ void main() {
|
||||
// Check that a second resolve of the same image is synchronous.
|
||||
expect(provider._lastResolvedConfiguration, isNotNull);
|
||||
final ImageStream stream = provider.resolve(provider._lastResolvedConfiguration);
|
||||
bool isSync;
|
||||
late bool isSync;
|
||||
final ImageStreamListener listener = ImageStreamListener((ImageInfo image, bool syncCall) { isSync = syncCall; });
|
||||
|
||||
// Still have live ref because frame has not pumped yet.
|
||||
await tester.pump();
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
|
||||
SchedulerBinding.instance.scheduleFrame();
|
||||
SchedulerBinding.instance!.scheduleFrame();
|
||||
await tester.pump();
|
||||
// Live ref should be gone - we didn't listen to the stream.
|
||||
expect(imageCache.liveImageCount, 0);
|
||||
expect(imageCache.currentSize, 0);
|
||||
expect(imageCache!.liveImageCount, 0);
|
||||
expect(imageCache!.currentSize, 0);
|
||||
|
||||
stream.addListener(listener);
|
||||
expect(isSync, true); // because the stream still has the image.
|
||||
|
||||
expect(imageCache.liveImageCount, 0);
|
||||
expect(imageCache.currentSize, 0);
|
||||
expect(imageCache!.liveImageCount, 0);
|
||||
expect(imageCache!.currentSize, 0);
|
||||
|
||||
expect(provider.loadCallCount, 1);
|
||||
});
|
||||
|
||||
testWidgets('precacheImage allows time to take over weak reference', (WidgetTester tester) async {
|
||||
final TestImageProvider provider = TestImageProvider();
|
||||
Future<void> precache;
|
||||
late Future<void> precache;
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -1564,39 +1563,39 @@ void main() {
|
||||
await precache;
|
||||
|
||||
// Should have ended up in the cache and have a weak reference.
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache.currentSize, 1);
|
||||
expect(imageCache.containsKey(provider), true);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
expect(imageCache!.currentSize, 1);
|
||||
expect(imageCache!.containsKey(provider), true);
|
||||
|
||||
// Check that a second resolve of the same image is synchronous.
|
||||
expect(provider._lastResolvedConfiguration, isNotNull);
|
||||
final ImageStream stream = provider.resolve(provider._lastResolvedConfiguration);
|
||||
bool isSync;
|
||||
late bool isSync;
|
||||
final ImageStreamListener listener = ImageStreamListener((ImageInfo image, bool syncCall) { isSync = syncCall; });
|
||||
|
||||
// Should have ended up in the cache and still have a weak reference.
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache.currentSize, 1);
|
||||
expect(imageCache.containsKey(provider), true);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
expect(imageCache!.currentSize, 1);
|
||||
expect(imageCache!.containsKey(provider), true);
|
||||
|
||||
stream.addListener(listener);
|
||||
expect(isSync, true);
|
||||
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache.currentSize, 1);
|
||||
expect(imageCache.containsKey(provider), true);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
expect(imageCache!.currentSize, 1);
|
||||
expect(imageCache!.containsKey(provider), true);
|
||||
|
||||
SchedulerBinding.instance.scheduleFrame();
|
||||
SchedulerBinding.instance!.scheduleFrame();
|
||||
await tester.pump();
|
||||
|
||||
expect(imageCache.liveImageCount, 1);
|
||||
expect(imageCache.currentSize, 1);
|
||||
expect(imageCache.containsKey(provider), true);
|
||||
expect(imageCache!.liveImageCount, 1);
|
||||
expect(imageCache!.currentSize, 1);
|
||||
expect(imageCache!.containsKey(provider), true);
|
||||
stream.removeListener(listener);
|
||||
|
||||
expect(imageCache.liveImageCount, 0);
|
||||
expect(imageCache.currentSize, 1);
|
||||
expect(imageCache.containsKey(provider), true);
|
||||
expect(imageCache!.liveImageCount, 0);
|
||||
expect(imageCache!.currentSize, 1);
|
||||
expect(imageCache!.containsKey(provider), true);
|
||||
expect(provider.loadCallCount, 1);
|
||||
});
|
||||
|
||||
@ -1617,29 +1616,29 @@ void main() {
|
||||
final List<Future<void>> futures = <Future<void>>[];
|
||||
await tester.pumpWidget(Builder(builder: (BuildContext context) {
|
||||
futures.add(precacheImage(provider, context));
|
||||
imageCache.evict(provider);
|
||||
imageCache!.evict(provider);
|
||||
futures.add(precacheImage(provider, context));
|
||||
return const SizedBox.expand();
|
||||
}));
|
||||
await Future.wait<void>(futures);
|
||||
expect(imageCache.statusForKey(provider).keepAlive, true);
|
||||
expect(imageCache.statusForKey(provider).live, true);
|
||||
expect(imageCache!.statusForKey(provider).keepAlive, true);
|
||||
expect(imageCache!.statusForKey(provider).live, true);
|
||||
|
||||
// Schedule a frame to get precacheImage to stop listening.
|
||||
SchedulerBinding.instance.scheduleFrame();
|
||||
SchedulerBinding.instance!.scheduleFrame();
|
||||
await tester.pump();
|
||||
expect(imageCache.statusForKey(provider).keepAlive, true);
|
||||
expect(imageCache.statusForKey(provider).live, false);
|
||||
expect(imageCache!.statusForKey(provider).keepAlive, true);
|
||||
expect(imageCache!.statusForKey(provider).live, false);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('errorBuilder - fails on key', (WidgetTester tester) async {
|
||||
final UniqueKey errorKey = UniqueKey();
|
||||
Object caughtException;
|
||||
late Object caughtException;
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: FailingImageProvider(failOnObtainKey: true, throws: 'threw', image: image10x10),
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
caughtException = error;
|
||||
return SizedBox.expand(key: errorKey);
|
||||
},
|
||||
@ -1655,11 +1654,11 @@ void main() {
|
||||
|
||||
testWidgets('errorBuilder - fails on load', (WidgetTester tester) async {
|
||||
final UniqueKey errorKey = UniqueKey();
|
||||
Object caughtException;
|
||||
late Object caughtException;
|
||||
await tester.pumpWidget(
|
||||
Image(
|
||||
image: FailingImageProvider(failOnLoad: true, throws: 'threw', image: image10x10),
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
caughtException = error;
|
||||
return SizedBox.expand(key: errorKey);
|
||||
},
|
||||
@ -1723,14 +1722,14 @@ void main() {
|
||||
);
|
||||
|
||||
testWidgets('Reports image size when painted', (WidgetTester tester) async {
|
||||
ImageSizeInfo imageSizeInfo;
|
||||
late ImageSizeInfo imageSizeInfo;
|
||||
int count = 0;
|
||||
debugOnPaintImage = (ImageSizeInfo info) {
|
||||
count += 1;
|
||||
imageSizeInfo = info;
|
||||
};
|
||||
|
||||
final ui.Image image = await tester.runAsync(() => createTestImage(width: 100, height: 100));
|
||||
final ui.Image image = (await tester.runAsync(() => createTestImage(width: 100, height: 100)))!;
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter(
|
||||
ImageInfo(
|
||||
image: image,
|
||||
@ -1764,9 +1763,9 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Disposes image handle when disposed', (WidgetTester tester) async {
|
||||
final ui.Image image = await tester.runAsync(() => createTestImage(width: 1, height: 1, cache: false));
|
||||
final ui.Image image = (await tester.runAsync(() => createTestImage(width: 1, height: 1, cache: false)))!;
|
||||
|
||||
expect(image.debugGetOpenHandleStackTraces().length, 1);
|
||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
||||
|
||||
final ImageProvider provider = TestImageProvider(
|
||||
streamCompleter: OneFrameImageStreamCompleter(
|
||||
@ -1782,17 +1781,17 @@ void main() {
|
||||
|
||||
// creating the provider should not have changed anything, and the provider
|
||||
// now owns the handle.
|
||||
expect(image.debugGetOpenHandleStackTraces().length, 1);
|
||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
||||
|
||||
await tester.pumpWidget(Image(image: provider));
|
||||
|
||||
// Image widget + 1, render object + 1
|
||||
expect(image.debugGetOpenHandleStackTraces().length, 3);
|
||||
expect(image.debugGetOpenHandleStackTraces()!.length, 3);
|
||||
|
||||
await tester.pumpWidget(const SizedBox());
|
||||
|
||||
// Image widget and render object go away
|
||||
expect(image.debugGetOpenHandleStackTraces().length, 1);
|
||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
||||
|
||||
await provider.evict();
|
||||
|
||||
@ -1801,12 +1800,12 @@ void main() {
|
||||
|
||||
// Image cache listener go away and Image stream listeners go away.
|
||||
// Image is now at zero.
|
||||
expect(image.debugGetOpenHandleStackTraces().length, 0);
|
||||
expect(image.debugGetOpenHandleStackTraces()!.length, 0);
|
||||
}, skip: kIsWeb); // Web does not care about image handle/disposal.
|
||||
|
||||
testWidgets('Keeps stream alive when ticker mode is disabled', (WidgetTester tester) async {
|
||||
imageCache.maximumSize = 0;
|
||||
final ui.Image image = await tester.runAsync(() => createTestImage(width: 1, height: 1, cache: false));
|
||||
imageCache!.maximumSize = 0;
|
||||
final ui.Image image = (await tester.runAsync(() => createTestImage(width: 1, height: 1, cache: false)))!;
|
||||
final TestImageProvider provider = TestImageProvider();
|
||||
provider.complete(image);
|
||||
|
||||
@ -1835,7 +1834,7 @@ void main() {
|
||||
|
||||
testWidgets('Load a good image after a bad image was loaded should not call errorBuilder', (WidgetTester tester) async {
|
||||
final UniqueKey errorKey = UniqueKey();
|
||||
final ui.Image image = await tester.runAsync(() => createTestImage());
|
||||
final ui.Image image = (await tester.runAsync(() => createTestImage()))!;
|
||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||
|
||||
@ -1847,10 +1846,10 @@ void main() {
|
||||
child: Image(
|
||||
image: imageProvider,
|
||||
excludeFromSemantics: true,
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
return Container(key: errorKey);
|
||||
},
|
||||
frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
return Padding(padding: const EdgeInsets.all(1), child: child);
|
||||
},
|
||||
),
|
||||
@ -1927,14 +1926,14 @@ class ConfigurationKeyedTestImageProvider extends TestImageProvider {
|
||||
}
|
||||
|
||||
class TestImageProvider extends ImageProvider<Object> {
|
||||
TestImageProvider({ImageStreamCompleter streamCompleter}) {
|
||||
TestImageProvider({ImageStreamCompleter? streamCompleter}) {
|
||||
_streamCompleter = streamCompleter
|
||||
?? OneFrameImageStreamCompleter(_completer.future);
|
||||
}
|
||||
|
||||
final Completer<ImageInfo> _completer = Completer<ImageInfo>();
|
||||
ImageStreamCompleter _streamCompleter;
|
||||
ImageConfiguration _lastResolvedConfiguration;
|
||||
late ImageStreamCompleter _streamCompleter;
|
||||
late ImageConfiguration _lastResolvedConfiguration;
|
||||
|
||||
bool get loadCalled => _loadCallCount > 0;
|
||||
int get loadCallCount => _loadCallCount;
|
||||
@ -1961,7 +1960,7 @@ class TestImageProvider extends ImageProvider<Object> {
|
||||
_completer.complete(ImageInfo(image: image));
|
||||
}
|
||||
|
||||
void fail(dynamic exception, StackTrace stackTrace) {
|
||||
void fail(Object exception, StackTrace? stackTrace) {
|
||||
_completer.completeError(exception, stackTrace);
|
||||
}
|
||||
|
||||
@ -1978,14 +1977,14 @@ class SimpleTestImageStreamCompleter extends ImageStreamCompleter {
|
||||
class TestImageStreamCompleter extends ImageStreamCompleter {
|
||||
TestImageStreamCompleter([this._currentImage]);
|
||||
|
||||
ImageInfo _currentImage;
|
||||
ImageInfo? _currentImage;
|
||||
final Set<ImageStreamListener> listeners = <ImageStreamListener>{};
|
||||
|
||||
@override
|
||||
void addListener(ImageStreamListener listener) {
|
||||
listeners.add(listener);
|
||||
if (_currentImage != null) {
|
||||
listener.onImage(_currentImage.clone(), true);
|
||||
listener.onImage(_currentImage!.clone(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1995,8 +1994,8 @@ class TestImageStreamCompleter extends ImageStreamCompleter {
|
||||
}
|
||||
|
||||
void setData({
|
||||
ImageInfo imageInfo,
|
||||
ImageChunkEvent chunkEvent,
|
||||
ImageInfo? imageInfo,
|
||||
ImageChunkEvent? chunkEvent,
|
||||
}) {
|
||||
if (imageInfo != null) {
|
||||
_currentImage?.dispose();
|
||||
@ -2008,21 +2007,19 @@ class TestImageStreamCompleter extends ImageStreamCompleter {
|
||||
listener.onImage(imageInfo.clone(), false);
|
||||
}
|
||||
if (chunkEvent != null && listener.onChunk != null) {
|
||||
listener.onChunk(chunkEvent);
|
||||
listener.onChunk!(chunkEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setError({
|
||||
dynamic exception,
|
||||
StackTrace stackTrace,
|
||||
required Object exception,
|
||||
StackTrace? stackTrace,
|
||||
}) {
|
||||
assert(exception != null, 'exception must not be null.');
|
||||
|
||||
final List<ImageStreamListener> localListeners = listeners.toList();
|
||||
for (final ImageStreamListener listener in localListeners) {
|
||||
if (listener.onError != null) {
|
||||
listener.onError(exception, stackTrace);
|
||||
listener.onError!(exception, stackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2059,8 +2056,8 @@ class FailingImageProvider extends ImageProvider<int> {
|
||||
const FailingImageProvider({
|
||||
this.failOnObtainKey = false,
|
||||
this.failOnLoad = false,
|
||||
@required this.throws,
|
||||
@required this.image,
|
||||
required this.throws,
|
||||
required this.image,
|
||||
}) : assert(failOnLoad != null),
|
||||
assert(failOnObtainKey != null),
|
||||
assert(failOnLoad == true || failOnObtainKey == true),
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -20,7 +18,7 @@ const Duration animationDuration = Duration(milliseconds:1000);
|
||||
const Duration additionalDelay = Duration(milliseconds:1);
|
||||
|
||||
void main() {
|
||||
MockOnEndFunction mockOnEndFunction;
|
||||
late MockOnEndFunction mockOnEndFunction;
|
||||
const Key switchKey = Key('switchKey');
|
||||
|
||||
setUp(() {
|
||||
@ -355,7 +353,7 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
Widget wrap({Widget child}) {
|
||||
Widget wrap({required Widget child}) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Material(
|
||||
@ -366,16 +364,13 @@ Widget wrap({Widget child}) {
|
||||
|
||||
class TestAnimatedWidget extends StatefulWidget {
|
||||
const TestAnimatedWidget({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.callback,
|
||||
this.switchKey,
|
||||
this.state,
|
||||
required this.switchKey,
|
||||
required this.state,
|
||||
}) : super(key: key);
|
||||
@required
|
||||
final VoidCallback callback;
|
||||
@required
|
||||
final VoidCallback? callback;
|
||||
final Key switchKey;
|
||||
@required
|
||||
final State<StatefulWidget> state;
|
||||
|
||||
@override
|
||||
@ -408,7 +403,6 @@ abstract class _TestAnimatedWidgetState extends State<TestAnimatedWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _TestAnimatedContainerWidgetState extends _TestAnimatedWidgetState {
|
||||
@override
|
||||
Widget getAnimatedWidget() {
|
||||
@ -553,7 +547,7 @@ class _TestTweenAnimationBuilderWidgetState extends _TestAnimatedWidgetState {
|
||||
tween: Tween<double>(begin: 1, end: 2),
|
||||
duration: duration,
|
||||
onEnd: widget.callback,
|
||||
builder: (BuildContext context, double size, Widget child) {
|
||||
builder: (BuildContext context, double? size, Widget? child) {
|
||||
return Container(
|
||||
child: child,
|
||||
width: size,
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
@ -13,7 +11,7 @@ const Size _kTestViewSize = Size(800.0, 600.0);
|
||||
class OffscreenRenderView extends RenderView {
|
||||
OffscreenRenderView() : super(
|
||||
configuration: const ViewConfiguration(size: _kTestViewSize),
|
||||
window: WidgetsBinding.instance.window,
|
||||
window: WidgetsBinding.instance!.window,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -32,7 +30,7 @@ class OffscreenWidgetTree {
|
||||
final RenderView renderView = OffscreenRenderView();
|
||||
final BuildOwner buildOwner = BuildOwner();
|
||||
final PipelineOwner pipelineOwner = PipelineOwner();
|
||||
RenderObjectToWidgetElement<RenderBox> root;
|
||||
RenderObjectToWidgetElement<RenderBox>? root;
|
||||
|
||||
void pumpWidget(Widget app) {
|
||||
root = RenderObjectToWidgetAdapter<RenderBox>(
|
||||
@ -44,7 +42,7 @@ class OffscreenWidgetTree {
|
||||
}
|
||||
|
||||
void pumpFrame() {
|
||||
buildOwner.buildScope(root);
|
||||
buildOwner.buildScope(root!);
|
||||
pipelineOwner.flushLayout();
|
||||
pipelineOwner.flushCompositingBits();
|
||||
pipelineOwner.flushPaint();
|
||||
@ -60,18 +58,18 @@ class Counter {
|
||||
}
|
||||
|
||||
class Trigger {
|
||||
VoidCallback callback;
|
||||
VoidCallback? callback;
|
||||
void fire() {
|
||||
if (callback != null)
|
||||
callback();
|
||||
callback!();
|
||||
}
|
||||
}
|
||||
|
||||
class TriggerableWidget extends StatefulWidget {
|
||||
const TriggerableWidget({
|
||||
Key key,
|
||||
this.trigger,
|
||||
this.counter,
|
||||
Key? key,
|
||||
required this.trigger,
|
||||
required this.counter,
|
||||
}) : super(key: key);
|
||||
|
||||
final Trigger trigger;
|
||||
@ -110,8 +108,8 @@ class TriggerableState extends State<TriggerableWidget> {
|
||||
|
||||
class TestFocusable extends StatefulWidget {
|
||||
const TestFocusable({
|
||||
Key key,
|
||||
this.focusNode,
|
||||
Key? key,
|
||||
required this.focusNode,
|
||||
this.autofocus = true,
|
||||
}) : super(key: key);
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/src/widgets/basic.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -19,7 +17,7 @@ void main() {
|
||||
return const SizedBox();
|
||||
}),
|
||||
));
|
||||
final InheritedElement element = key.currentContext as InheritedElement;
|
||||
final InheritedElement element = key.currentContext! as InheritedElement;
|
||||
expect(
|
||||
element.toStringDeep(minLevel: DiagnosticLevel.info),
|
||||
equalsIgnoringHashCodes(
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -13,28 +11,28 @@ import 'package:flutter/material.dart';
|
||||
// valued fields: a, b, c.
|
||||
class ABCModel extends InheritedModel<String> {
|
||||
const ABCModel({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.a,
|
||||
this.b,
|
||||
this.c,
|
||||
this.aspects,
|
||||
Widget child,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
final int a;
|
||||
final int b;
|
||||
final int c;
|
||||
final int? a;
|
||||
final int? b;
|
||||
final int? c;
|
||||
|
||||
// The aspects (fields) of this model that widgets can depend on with
|
||||
// inheritFrom.
|
||||
//
|
||||
// This property is null by default, which means that the model supports
|
||||
// all 3 fields.
|
||||
final Set<String> aspects;
|
||||
final Set<String>? aspects;
|
||||
|
||||
@override
|
||||
bool isSupportedAspect(Object aspect) {
|
||||
return aspect == null || aspects == null || aspects.contains(aspect);
|
||||
return aspect == null || aspects == null || aspects!.contains(aspect);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -50,13 +48,13 @@ class ABCModel extends InheritedModel<String> {
|
||||
|| (c != old.c && dependencies.contains('c'));
|
||||
}
|
||||
|
||||
static ABCModel of(BuildContext context, { String fieldName }) {
|
||||
static ABCModel? of(BuildContext context, { String? fieldName }) {
|
||||
return InheritedModel.inheritFrom<ABCModel>(context, aspect: fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
class ShowABCField extends StatefulWidget {
|
||||
const ShowABCField({ Key key, this.fieldName }) : super(key: key);
|
||||
const ShowABCField({ Key? key, required this.fieldName }) : super(key: key);
|
||||
|
||||
final String fieldName;
|
||||
|
||||
@ -69,8 +67,8 @@ class _ShowABCFieldState extends State<ShowABCField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ABCModel abc = ABCModel.of(context, fieldName: widget.fieldName);
|
||||
final int value = widget.fieldName == 'a' ? abc.a : (widget.fieldName == 'b' ? abc.b : abc.c);
|
||||
final ABCModel abc = ABCModel.of(context, fieldName: widget.fieldName)!;
|
||||
final int? value = widget.fieldName == 'a' ? abc.a : (widget.fieldName == 'b' ? abc.b : abc.c);
|
||||
return Text('${widget.fieldName}: $value [${_buildCount++}]');
|
||||
}
|
||||
}
|
||||
@ -91,7 +89,7 @@ void main() {
|
||||
// aspect of the model changes.
|
||||
final Widget showABC = Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ABCModel abc = ABCModel.of(context);
|
||||
final ABCModel abc = ABCModel.of(context)!;
|
||||
return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}');
|
||||
}
|
||||
);
|
||||
@ -193,7 +191,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Looking up an non existent InheritedModel ancestor returns null', (WidgetTester tester) async {
|
||||
ABCModel inheritedModel;
|
||||
ABCModel? inheritedModel;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Builder(
|
||||
@ -228,8 +226,8 @@ void main() {
|
||||
// Which is the inner model, for which b,c are null.
|
||||
final Widget showABC = Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ABCModel abc = ABCModel.of(context);
|
||||
return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.headline6);
|
||||
final ABCModel abc = ABCModel.of(context)!;
|
||||
return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context)!.textTheme.headline6);
|
||||
}
|
||||
);
|
||||
|
||||
@ -330,7 +328,7 @@ void main() {
|
||||
int _a = 0;
|
||||
int _b = 1;
|
||||
int _c = 2;
|
||||
Set<String> _innerModelAspects = <String>{'a'};
|
||||
Set<String>? _innerModelAspects = <String>{'a'};
|
||||
|
||||
// Same as in abcPage in the "Inner InheritedModel shadows the outer one"
|
||||
// test except: the "Add b aspect" changes adds 'b' to the set of
|
||||
@ -345,8 +343,8 @@ void main() {
|
||||
// Which is the inner model, for which b,c are null.
|
||||
final Widget showABC = Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ABCModel abc = ABCModel.of(context);
|
||||
return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.headline6);
|
||||
final ABCModel abc = ABCModel.of(context)!;
|
||||
return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context)!.textTheme.headline6);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -2,15 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'test_widgets.dart';
|
||||
|
||||
class TestInherited extends InheritedWidget {
|
||||
const TestInherited({ Key key, Widget child, this.shouldNotify = true })
|
||||
const TestInherited({ Key? key, required Widget child, this.shouldNotify = true })
|
||||
: super(key: key, child: child);
|
||||
|
||||
final bool shouldNotify;
|
||||
@ -22,7 +20,7 @@ class TestInherited extends InheritedWidget {
|
||||
}
|
||||
|
||||
class ValueInherited extends InheritedWidget {
|
||||
const ValueInherited({ Key key, Widget child, this.value })
|
||||
const ValueInherited({ Key? key, required Widget child, required this.value })
|
||||
: super(key: key, child: child);
|
||||
|
||||
final int value;
|
||||
@ -32,7 +30,7 @@ class ValueInherited extends InheritedWidget {
|
||||
}
|
||||
|
||||
class ExpectFail extends StatefulWidget {
|
||||
const ExpectFail(this.onError, { Key key }) : super(key: key);
|
||||
const ExpectFail(this.onError, { Key? key }) : super(key: key);
|
||||
final VoidCallback onError;
|
||||
|
||||
@override
|
||||
@ -55,7 +53,7 @@ class ExpectFailState extends State<ExpectFail> {
|
||||
}
|
||||
|
||||
class ChangeNotifierInherited extends InheritedNotifier<ChangeNotifier> {
|
||||
const ChangeNotifierInherited({ Key key, Widget child, ChangeNotifier notifier })
|
||||
const ChangeNotifierInherited({ Key? key, required Widget child, ChangeNotifier? notifier })
|
||||
: super(key: key, child: child, notifier: notifier);
|
||||
}
|
||||
|
||||
@ -65,7 +63,7 @@ void main() {
|
||||
|
||||
final Builder builder = Builder(
|
||||
builder: (BuildContext context) {
|
||||
log.add(context.dependOnInheritedWidgetOfExactType<TestInherited>());
|
||||
log.add(context.dependOnInheritedWidgetOfExactType<TestInherited>()!);
|
||||
return Container();
|
||||
}
|
||||
);
|
||||
@ -97,7 +95,7 @@ void main() {
|
||||
key: globalKey,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
log.add(context.dependOnInheritedWidgetOfExactType<TestInherited>());
|
||||
log.add(context.dependOnInheritedWidgetOfExactType<TestInherited>()!);
|
||||
return Container();
|
||||
}
|
||||
),
|
||||
@ -134,7 +132,7 @@ void main() {
|
||||
child: Container(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>()!;
|
||||
log.add('a: ${v.value}');
|
||||
return const Text('', textDirection: TextDirection.ltr);
|
||||
}
|
||||
@ -151,7 +149,7 @@ void main() {
|
||||
child: Container(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>()!;
|
||||
log.add('b: ${v.value}');
|
||||
return const Text('', textDirection: TextDirection.ltr);
|
||||
}
|
||||
@ -209,7 +207,7 @@ void main() {
|
||||
key: key,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>()!;
|
||||
log.add('a: ${v.value}');
|
||||
return const Text('', textDirection: TextDirection.ltr);
|
||||
}
|
||||
@ -227,7 +225,7 @@ void main() {
|
||||
key: key,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>()!;
|
||||
log.add('b: ${v.value}');
|
||||
return const Text('', textDirection: TextDirection.ltr);
|
||||
}
|
||||
@ -270,7 +268,7 @@ void main() {
|
||||
|
||||
final Widget child = Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>()!;
|
||||
log.add(v.value);
|
||||
return const Text('', textDirection: TextDirection.ltr);
|
||||
}
|
||||
@ -341,7 +339,7 @@ void main() {
|
||||
final Widget child = Builder(
|
||||
key: GlobalKey(),
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited v = context.dependOnInheritedWidgetOfExactType<ValueInherited>()!;
|
||||
log.add(v.value);
|
||||
return const Text('', textDirection: TextDirection.ltr);
|
||||
},
|
||||
@ -382,13 +380,13 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Inherited widget notifies descendants when descendant previously failed to find a match', (WidgetTester tester) async {
|
||||
int inheritedValue = -1;
|
||||
int? inheritedValue = -1;
|
||||
|
||||
final Widget inner = Container(
|
||||
key: GlobalKey(),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
final ValueInherited widget = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
final ValueInherited? widget = context.dependOnInheritedWidgetOfExactType<ValueInherited>();
|
||||
inheritedValue = widget?.value;
|
||||
return Container();
|
||||
}
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
@ -14,7 +12,7 @@ class TestRoute extends PageRouteBuilder<void> {
|
||||
}
|
||||
|
||||
class IconTextBox extends StatelessWidget {
|
||||
const IconTextBox(this.text, { Key key }) : super(key: key);
|
||||
const IconTextBox(this.text, { Key? key }) : super(key: key);
|
||||
final String text;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -34,7 +32,7 @@ void main() {
|
||||
const Color textColor = Color(0xFF00FF00);
|
||||
const Color iconColor = Color(0xFF0000FF);
|
||||
bool useCaptureAll = false;
|
||||
BuildContext navigatorContext;
|
||||
late BuildContext navigatorContext;
|
||||
|
||||
Widget buildFrame() {
|
||||
return WidgetsApp(
|
||||
@ -61,7 +59,7 @@ void main() {
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
navigatorContext = context;
|
||||
Navigator.of(context).push(
|
||||
Navigator.of(context)!.push(
|
||||
TestRoute(
|
||||
useCaptureAll
|
||||
? InheritedTheme.captureAll(context, const IconTextBox('Hello'))
|
||||
@ -88,7 +86,7 @@ void main() {
|
||||
of: find.byType(Icon),
|
||||
matching: find.byType(RichText),
|
||||
),
|
||||
).text.style;
|
||||
).text.style!;
|
||||
}
|
||||
|
||||
TextStyle getTextStyle(String text) {
|
||||
@ -97,7 +95,7 @@ void main() {
|
||||
of: find.text(text),
|
||||
matching: find.byType(RichText),
|
||||
),
|
||||
).text.style;
|
||||
).text.style!;
|
||||
}
|
||||
|
||||
useCaptureAll = false;
|
||||
@ -123,7 +121,7 @@ void main() {
|
||||
|
||||
// Return to the home route
|
||||
useCaptureAll = true;
|
||||
Navigator.of(navigatorContext).pop();
|
||||
Navigator.of(navigatorContext)!.pop();
|
||||
await tester.pumpAndSettle(); // route transition
|
||||
|
||||
// Verify that all is the same as it was when the test started
|
||||
@ -199,7 +197,7 @@ void main() {
|
||||
of: find.byKey(key),
|
||||
matching: find.byType(RichText),
|
||||
),
|
||||
).text.style;
|
||||
).text.style!;
|
||||
}
|
||||
|
||||
expect(getIconStyle(icon1).color, innerColor);
|
||||
@ -245,7 +243,7 @@ void main() {
|
||||
of: find.text(text),
|
||||
matching: find.byType(RichText),
|
||||
),
|
||||
).text.style;
|
||||
).text.style!;
|
||||
}
|
||||
|
||||
expect(getTextStyle('Hello').fontSize, null);
|
||||
|
||||
@ -2,15 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
List<String> ancestors = <String>[];
|
||||
|
||||
class TestWidget extends StatefulWidget {
|
||||
const TestWidget({ Key key }) : super(key: key);
|
||||
const TestWidget({ Key? key }) : super(key: key);
|
||||
@override
|
||||
TestWidgetState createState() => TestWidgetState();
|
||||
}
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -625,11 +623,11 @@ void main() {
|
||||
|
||||
testWidgets('Scale with mouse returns onInteraction properties', (WidgetTester tester) async{
|
||||
final TransformationController transformationController = TransformationController();
|
||||
Offset focalPoint;
|
||||
Offset localFocalPoint;
|
||||
double scaleChange;
|
||||
Velocity currentVelocity;
|
||||
bool calledStart;
|
||||
late Offset focalPoint;
|
||||
late Offset localFocalPoint;
|
||||
late double scaleChange;
|
||||
late Velocity currentVelocity;
|
||||
late bool calledStart;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -677,11 +675,11 @@ void main() {
|
||||
|
||||
testWidgets('onInteraction can be used to get scene point', (WidgetTester tester) async{
|
||||
final TransformationController transformationController = TransformationController();
|
||||
Offset focalPoint;
|
||||
Offset localFocalPoint;
|
||||
double scaleChange;
|
||||
Velocity currentVelocity;
|
||||
bool calledStart;
|
||||
late Offset focalPoint;
|
||||
late Offset localFocalPoint;
|
||||
late double scaleChange;
|
||||
late Velocity currentVelocity;
|
||||
late bool calledStart;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user