add missing trailing commas (#80995)
This commit is contained in:
parent
4a79bc96d6
commit
d36d5ae35d
@ -94,12 +94,18 @@ void main() {
|
||||
expect(AlignmentDirectional.bottomEnd.resolve(TextDirection.rtl), Alignment.bottomLeft);
|
||||
expect(AlignmentDirectional(nonconst(1.0), 2.0), AlignmentDirectional(nonconst(1.0), 2.0));
|
||||
expect(const AlignmentDirectional(1.0, 2.0), isNot(const AlignmentDirectional(2.0, 1.0)));
|
||||
expect(AlignmentDirectional.centerStart.resolve(TextDirection.ltr),
|
||||
AlignmentDirectional.centerEnd.resolve(TextDirection.rtl));
|
||||
expect(AlignmentDirectional.centerStart.resolve(TextDirection.ltr),
|
||||
isNot(AlignmentDirectional.centerEnd.resolve(TextDirection.ltr)));
|
||||
expect(AlignmentDirectional.centerEnd.resolve(TextDirection.ltr),
|
||||
isNot(AlignmentDirectional.centerEnd.resolve(TextDirection.rtl)));
|
||||
expect(
|
||||
AlignmentDirectional.centerStart.resolve(TextDirection.ltr),
|
||||
AlignmentDirectional.centerEnd.resolve(TextDirection.rtl),
|
||||
);
|
||||
expect(
|
||||
AlignmentDirectional.centerStart.resolve(TextDirection.ltr),
|
||||
isNot(AlignmentDirectional.centerEnd.resolve(TextDirection.ltr)),
|
||||
);
|
||||
expect(
|
||||
AlignmentDirectional.centerEnd.resolve(TextDirection.ltr),
|
||||
isNot(AlignmentDirectional.centerEnd.resolve(TextDirection.rtl)),
|
||||
);
|
||||
});
|
||||
|
||||
test('AlignmentGeometry.lerp ad hoc tests', () {
|
||||
|
@ -68,7 +68,7 @@ void main() {
|
||||
excludes: const <Offset>[ Offset(10.0, 20.0), Offset(30.0, 40.0) ],
|
||||
);
|
||||
const BeveledRectangleBorder border = BeveledRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0))
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
);
|
||||
expect(border.getOuterPath(rect), looksLikeRect);
|
||||
expect(border.getInnerPath(rect), looksLikeRect);
|
||||
|
@ -19,13 +19,12 @@ Future<void> main() async {
|
||||
Future<ImageInfo>.value(ImageInfo(
|
||||
image: image,
|
||||
scale: 1.0,
|
||||
),
|
||||
)));
|
||||
)),
|
||||
));
|
||||
|
||||
await tester.idle();
|
||||
expect(imageCache!.currentSize, 1);
|
||||
final ByteData message = const JSONMessageCodec().encodeMessage(
|
||||
<String, dynamic>{'type': 'memoryPressure'})!;
|
||||
final ByteData message = const JSONMessageCodec().encodeMessage(<String, dynamic>{'type': 'memoryPressure'})!;
|
||||
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('flutter/system', message, (_) { });
|
||||
expect(imageCache!.currentSize, 0);
|
||||
});
|
||||
|
@ -145,7 +145,7 @@ void main() {
|
||||
' However, only Border and BorderDirectional classes are supported\n'
|
||||
' by this method.\n'
|
||||
' For a more general interpolation method, consider using\n'
|
||||
' ShapeBorder.lerp instead.\n'
|
||||
' ShapeBorder.lerp instead.\n',
|
||||
));
|
||||
});
|
||||
|
||||
|
@ -101,11 +101,9 @@ void main() {
|
||||
final BoxShadow shadow4 = BoxShadow.lerp(shadow2, shadow3, 0.5)!;
|
||||
expect(shadow4.blurRadius, equals(2.0));
|
||||
|
||||
List<BoxShadow> shadowList = BoxShadow.lerpList(
|
||||
<BoxShadow>[shadow2, shadow1], <BoxShadow>[shadow3], 0.5)!;
|
||||
List<BoxShadow> shadowList = BoxShadow.lerpList(<BoxShadow>[shadow2, shadow1], <BoxShadow>[shadow3], 0.5)!;
|
||||
expect(shadowList, equals(<BoxShadow>[shadow4, shadow1.scale(0.5)]));
|
||||
shadowList = BoxShadow.lerpList(
|
||||
<BoxShadow>[shadow2], <BoxShadow>[shadow3, shadow1], 0.5)!;
|
||||
shadowList = BoxShadow.lerpList(<BoxShadow>[shadow2], <BoxShadow>[shadow3, shadow1], 0.5)!;
|
||||
expect(shadowList, equals(<BoxShadow>[shadow4, shadow1.scale(0.5)]));
|
||||
});
|
||||
|
||||
|
@ -447,12 +447,11 @@ void main() {
|
||||
};
|
||||
const MaterialColor first = MaterialColor(0, sampleMap);
|
||||
const MaterialColor second = MaterialColor(0, sampleMap);
|
||||
const MaterialColor third = MaterialColor(
|
||||
0, <int, MaterialColor>{
|
||||
0: Colors.lightBlue,
|
||||
1: Colors.deepOrange,
|
||||
2: Colors.blueGrey,
|
||||
});
|
||||
const MaterialColor third = MaterialColor(0, <int, MaterialColor>{
|
||||
0: Colors.lightBlue,
|
||||
1: Colors.deepOrange,
|
||||
2: Colors.blueGrey,
|
||||
});
|
||||
expect(first == second, true);
|
||||
expect(first == third, true);
|
||||
});
|
||||
|
@ -67,7 +67,7 @@ void main() {
|
||||
excludes: const <Offset>[ Offset(10.0, 20.0), Offset(30.0, 40.0) ],
|
||||
);
|
||||
const ContinuousRectangleBorder border = ContinuousRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0))
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
);
|
||||
expect(border.getOuterPath(rect), looksLikeRect);
|
||||
expect(border.getInnerPath(rect), looksLikeRect);
|
||||
|
@ -37,7 +37,7 @@ class SynchronousTestImageProvider extends ImageProvider<int> {
|
||||
@override
|
||||
ImageStreamCompleter load(int key, DecoderCallback decode) {
|
||||
return OneFrameImageStreamCompleter(
|
||||
SynchronousFuture<ImageInfo>(TestImageInfo(key, image: image, scale: 1.0))
|
||||
SynchronousFuture<ImageInfo>(TestImageInfo(key, image: image, scale: 1.0)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -71,7 +71,7 @@ class AsyncTestImageProvider extends ImageProvider<int> {
|
||||
@override
|
||||
ImageStreamCompleter load(int key, DecoderCallback decode) {
|
||||
return OneFrameImageStreamCompleter(
|
||||
Future<ImageInfo>.value(TestImageInfo(key, image: image))
|
||||
Future<ImageInfo>.value(TestImageInfo(key, image: image)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -254,7 +254,7 @@ void main() {
|
||||
|
||||
final TestCanvas canvas = TestCanvas();
|
||||
const ImageConfiguration imageConfiguration = ImageConfiguration(
|
||||
size: Size(100.0, 100.0)
|
||||
size: Size(100.0, 100.0),
|
||||
);
|
||||
bool onChangedCalled = false;
|
||||
final BoxPainter boxPainter = boxDecoration.createBoxPainter(() {
|
||||
@ -327,8 +327,7 @@ void main() {
|
||||
image: SynchronousTestImageProvider(image),
|
||||
matchTextDirection: true,
|
||||
);
|
||||
final BoxDecoration boxDecoration = BoxDecoration(
|
||||
image: backgroundImage);
|
||||
final BoxDecoration boxDecoration = BoxDecoration(image: backgroundImage);
|
||||
final BoxPainter boxPainter = boxDecoration.createBoxPainter(() {
|
||||
assert(false);
|
||||
});
|
||||
@ -336,7 +335,9 @@ void main() {
|
||||
late FlutterError error;
|
||||
try {
|
||||
boxPainter.paint(canvas, Offset.zero, const ImageConfiguration(
|
||||
size: Size(100.0, 100.0), textDirection: null));
|
||||
size: Size(100.0, 100.0),
|
||||
textDirection: null,
|
||||
));
|
||||
} on FlutterError catch (e) {
|
||||
error = e;
|
||||
}
|
||||
@ -354,7 +355,7 @@ void main() {
|
||||
' DecorationImage(SynchronousTestImageProvider(),\n'
|
||||
' Alignment.center, match text direction, scale: 1.0)\n'
|
||||
' The ImageConfiguration was:\n'
|
||||
' ImageConfiguration(size: Size(100.0, 100.0))\n'
|
||||
' ImageConfiguration(size: Size(100.0, 100.0))\n',
|
||||
);
|
||||
}, skip: kIsWeb);
|
||||
|
||||
@ -364,7 +365,7 @@ void main() {
|
||||
image: const SynchronousErrorTestImageProvider('threw'),
|
||||
onError: (dynamic error, StackTrace? stackTrace) {
|
||||
exception = error as String;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
backgroundImage.createPainter(() { }).paint(
|
||||
@ -662,7 +663,7 @@ void main() {
|
||||
final DecorationImage backgroundImage = DecorationImage(
|
||||
image: SynchronousTestImageProvider(image),
|
||||
scale: 4,
|
||||
alignment: Alignment.topLeft
|
||||
alignment: Alignment.topLeft,
|
||||
);
|
||||
|
||||
final BoxDecoration boxDecoration = BoxDecoration(image: backgroundImage);
|
||||
|
@ -23,11 +23,15 @@ void main() {
|
||||
expect(insets.along(Axis.horizontal), equals(16.0));
|
||||
expect(insets.along(Axis.vertical), equals(20.0));
|
||||
|
||||
expect(insets.inflateRect(const Rect.fromLTRB(23.0, 32.0, 124.0, 143.0)),
|
||||
const Rect.fromLTRB(18.0, 25.0, 135.0, 156.0));
|
||||
expect(
|
||||
insets.inflateRect(const Rect.fromLTRB(23.0, 32.0, 124.0, 143.0)),
|
||||
const Rect.fromLTRB(18.0, 25.0, 135.0, 156.0),
|
||||
);
|
||||
|
||||
expect(insets.deflateRect(const Rect.fromLTRB(23.0, 32.0, 124.0, 143.0)),
|
||||
const Rect.fromLTRB(28.0, 39.0, 113.0, 130.0));
|
||||
expect(
|
||||
insets.deflateRect(const Rect.fromLTRB(23.0, 32.0, 124.0, 143.0)),
|
||||
const Rect.fromLTRB(28.0, 39.0, 113.0, 130.0),
|
||||
);
|
||||
|
||||
expect(insets.inflateSize(const Size(100.0, 125.0)), const Size(116.0, 145.0));
|
||||
expect(insets.deflateSize(const Size(100.0, 125.0)), const Size(84.0, 105.0));
|
||||
@ -66,12 +70,18 @@ void main() {
|
||||
expect(const EdgeInsetsDirectional.only(bottom: 963.25).resolve(TextDirection.rtl), const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 963.25));
|
||||
expect(EdgeInsetsDirectional.only(), EdgeInsetsDirectional.only()); // ignore: prefer_const_constructors
|
||||
expect(const EdgeInsetsDirectional.only(top: 1.0), isNot(const EdgeInsetsDirectional.only(bottom: 1.0)));
|
||||
expect(const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.ltr),
|
||||
const EdgeInsetsDirectional.fromSTEB(30.0, 20.0, 10.0, 40.0).resolve(TextDirection.rtl));
|
||||
expect(const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.ltr),
|
||||
isNot(const EdgeInsetsDirectional.fromSTEB(30.0, 20.0, 10.0, 40.0).resolve(TextDirection.ltr)));
|
||||
expect(const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.ltr),
|
||||
isNot(const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.rtl)));
|
||||
expect(
|
||||
const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.ltr),
|
||||
const EdgeInsetsDirectional.fromSTEB(30.0, 20.0, 10.0, 40.0).resolve(TextDirection.rtl),
|
||||
);
|
||||
expect(
|
||||
const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.ltr),
|
||||
isNot(const EdgeInsetsDirectional.fromSTEB(30.0, 20.0, 10.0, 40.0).resolve(TextDirection.ltr)),
|
||||
);
|
||||
expect(
|
||||
const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.ltr),
|
||||
isNot(const EdgeInsetsDirectional.fromSTEB(10.0, 20.0, 30.0, 40.0).resolve(TextDirection.rtl)),
|
||||
);
|
||||
});
|
||||
|
||||
test('EdgeInsets equality', () {
|
||||
|
@ -63,7 +63,7 @@ void main() {
|
||||
expect(
|
||||
start.toString(),
|
||||
equals(
|
||||
'FlutterLogoDecoration(textColor: Color(0xffd4f144), style: stacked)'
|
||||
'FlutterLogoDecoration(textColor: Color(0xffd4f144), style: stacked)',
|
||||
),
|
||||
);
|
||||
expect(
|
||||
|
@ -801,7 +801,7 @@ void main() {
|
||||
child: RepaintBoundary(
|
||||
key: painterKey,
|
||||
child: CustomPaint(
|
||||
painter: GradientPainter(shader, rect)
|
||||
painter: GradientPainter(shader, rect),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -23,7 +23,7 @@ void main() {
|
||||
stream.addListener(ImageStreamListener(
|
||||
(ImageInfo image, bool synchronousCall) {
|
||||
completer.complete();
|
||||
}
|
||||
},
|
||||
));
|
||||
imageCache!.clearLiveImages();
|
||||
await completer.future;
|
||||
|
@ -136,8 +136,10 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
Future<Size> _resolveAndGetSize(ImageProvider imageProvider,
|
||||
{ImageConfiguration configuration = ImageConfiguration.empty}) async {
|
||||
Future<Size> _resolveAndGetSize(
|
||||
ImageProvider imageProvider, {
|
||||
ImageConfiguration configuration = ImageConfiguration.empty,
|
||||
}) async {
|
||||
final ImageStream stream = imageProvider.resolve(configuration);
|
||||
final Completer<Size> completer = Completer<Size>();
|
||||
final ImageStreamListener listener =
|
||||
|
@ -24,8 +24,7 @@ class TestAssetBundle extends CachingAssetBundle {
|
||||
@override
|
||||
Future<ByteData> load(String key) async {
|
||||
if (key == 'AssetManifest.json')
|
||||
return ByteData.view(Uint8List.fromList(
|
||||
const Utf8Encoder().convert(_assetBundleContents)).buffer);
|
||||
return ByteData.view(Uint8List.fromList(const Utf8Encoder().convert(_assetBundleContents)).buffer);
|
||||
|
||||
loadCallCount[key] = loadCallCount[key] ?? 0 + 1;
|
||||
if (key == 'one')
|
||||
@ -43,8 +42,9 @@ void main() {
|
||||
assetBundleMap[mainAssetPath] = <String>[];
|
||||
|
||||
final AssetImage assetImage = AssetImage(
|
||||
mainAssetPath,
|
||||
bundle: TestAssetBundle(assetBundleMap));
|
||||
mainAssetPath,
|
||||
bundle: TestAssetBundle(assetBundleMap),
|
||||
);
|
||||
const ImageConfiguration configuration = ImageConfiguration.empty;
|
||||
|
||||
assetImage.obtainKey(configuration)
|
||||
@ -90,12 +90,12 @@ void main() {
|
||||
|
||||
assetBundleMap[mainAssetPath] = <String>[mainAssetPath, variantPath];
|
||||
|
||||
final TestAssetBundle testAssetBundle = TestAssetBundle(
|
||||
assetBundleMap);
|
||||
final TestAssetBundle testAssetBundle = TestAssetBundle(assetBundleMap);
|
||||
|
||||
final AssetImage assetImage = AssetImage(
|
||||
mainAssetPath,
|
||||
bundle: testAssetBundle);
|
||||
mainAssetPath,
|
||||
bundle: testAssetBundle,
|
||||
);
|
||||
|
||||
// we have the exact match for this scale, let's use it
|
||||
assetImage.obtainKey(ImageConfiguration.empty)
|
||||
@ -122,12 +122,12 @@ void main() {
|
||||
|
||||
assetBundleMap[mainAssetPath] = <String>[mainAssetPath];
|
||||
|
||||
final TestAssetBundle testAssetBundle = TestAssetBundle(
|
||||
assetBundleMap);
|
||||
final TestAssetBundle testAssetBundle = TestAssetBundle(assetBundleMap);
|
||||
|
||||
final AssetImage assetImage = AssetImage(
|
||||
mainAssetPath,
|
||||
bundle: TestAssetBundle(assetBundleMap));
|
||||
mainAssetPath,
|
||||
bundle: TestAssetBundle(assetBundleMap),
|
||||
);
|
||||
|
||||
|
||||
assetImage.obtainKey(ImageConfiguration.empty)
|
||||
@ -138,8 +138,8 @@ void main() {
|
||||
|
||||
assetImage.obtainKey(ImageConfiguration(
|
||||
bundle: testAssetBundle,
|
||||
devicePixelRatio: 3.0),
|
||||
).then(expectAsync1((AssetBundleImageKey bundleKey) {
|
||||
devicePixelRatio: 3.0,
|
||||
)).then(expectAsync1((AssetBundleImageKey bundleKey) {
|
||||
expect(bundleKey.name, mainAssetPath);
|
||||
expect(bundleKey.scale, 1.0);
|
||||
}));
|
||||
@ -161,18 +161,18 @@ void main() {
|
||||
|
||||
assetBundleMap[mainAssetPath] = <String>[mainAssetPath, variantPath];
|
||||
|
||||
final TestAssetBundle testAssetBundle = TestAssetBundle(
|
||||
assetBundleMap);
|
||||
final TestAssetBundle testAssetBundle = TestAssetBundle(assetBundleMap);
|
||||
|
||||
final AssetImage assetImage = AssetImage(
|
||||
mainAssetPath,
|
||||
bundle: testAssetBundle);
|
||||
mainAssetPath,
|
||||
bundle: testAssetBundle,
|
||||
);
|
||||
|
||||
// we have 1.0 and 3.0, asking for 1.5 should give
|
||||
assetImage.obtainKey(ImageConfiguration(
|
||||
bundle: testAssetBundle,
|
||||
devicePixelRatio: deviceRatio),
|
||||
).then(expectAsync1((AssetBundleImageKey bundleKey) {
|
||||
devicePixelRatio: deviceRatio,
|
||||
)).then(expectAsync1((AssetBundleImageKey bundleKey) {
|
||||
expect(bundleKey.name, expectedAssetPath);
|
||||
expect(bundleKey.scale, chosenAssetRatio);
|
||||
}));
|
||||
|
@ -75,7 +75,7 @@ class TestImageProvider extends ImageProvider<int> {
|
||||
@override
|
||||
ImageStreamCompleter load(int key, DecoderCallback decode) {
|
||||
return OneFrameImageStreamCompleter(
|
||||
SynchronousFuture<ImageInfo>(TestImageInfo(imageValue, image: image.clone()))
|
||||
SynchronousFuture<ImageInfo>(TestImageInfo(imageValue, image: image.clone())),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,10 @@ void main() {
|
||||
const RoundedRectangleBorder directional = RoundedRectangleBorder(
|
||||
borderRadius: BorderRadiusDirectional.only(topStart: Radius.circular(20)),
|
||||
);
|
||||
expect(ShapeBorder.lerp(directional, c10, 1.0),
|
||||
ShapeBorder.lerp(c10, directional, 0.0));
|
||||
expect(
|
||||
ShapeBorder.lerp(directional, c10, 1.0),
|
||||
ShapeBorder.lerp(c10, directional, 0.0),
|
||||
);
|
||||
});
|
||||
|
||||
test('RoundedRectangleBorder and CircleBorder', () {
|
||||
@ -86,19 +88,31 @@ void main() {
|
||||
expect(ShapeBorder.lerp(c, ShapeBorder.lerp(r, c, 0.1), 0.1)!.getOuterPath(rect), looksLikeC);
|
||||
expect(ShapeBorder.lerp(c, ShapeBorder.lerp(r, c, 0.1), 0.9)!.getOuterPath(rect), looksLikeR);
|
||||
|
||||
expect(ShapeBorder.lerp(r, c, 0.1).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(r, c, 0.2).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(ShapeBorder.lerp(r, c, 0.1), ShapeBorder.lerp(r, c, 0.9), 0.9).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)');
|
||||
expect(
|
||||
ShapeBorder.lerp(r, c, 0.1).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(r, c, 0.2).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(ShapeBorder.lerp(r, c, 0.1), ShapeBorder.lerp(r, c, 0.9), 0.9).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
|
||||
expect(ShapeBorder.lerp(c, r, 0.9).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(c, r, 0.8).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(ShapeBorder.lerp(r, c, 0.9), ShapeBorder.lerp(r, c, 0.1), 0.1).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)');
|
||||
expect(
|
||||
ShapeBorder.lerp(c, r, 0.9).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(c, r, 0.8).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(ShapeBorder.lerp(r, c, 0.9), ShapeBorder.lerp(r, c, 0.1), 0.1).toString(),
|
||||
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
|
||||
expect(ShapeBorder.lerp(r, c, 0.1), ShapeBorder.lerp(r, c, 0.1));
|
||||
expect(ShapeBorder.lerp(r, c, 0.1).hashCode, ShapeBorder.lerp(r, c, 0.1).hashCode);
|
||||
|
@ -74,19 +74,31 @@ void main() {
|
||||
expect(ShapeBorder.lerp(circle, ShapeBorder.lerp(stadium, circle, 0.1), 0.1)!.getOuterPath(rect), looksLikeC);
|
||||
expect(ShapeBorder.lerp(circle, ShapeBorder.lerp(stadium, circle, 0.1), 0.9)!.getOuterPath(rect), looksLikeS);
|
||||
|
||||
expect(ShapeBorder.lerp(stadium, circle, 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 10.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(stadium, circle, 0.2).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 20.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(ShapeBorder.lerp(stadium, circle, 0.1), ShapeBorder.lerp(stadium, circle, 0.9), 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 82.0% of the way to being a CircleBorder)');
|
||||
expect(
|
||||
ShapeBorder.lerp(stadium, circle, 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 10.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(stadium, circle, 0.2).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 20.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(ShapeBorder.lerp(stadium, circle, 0.1), ShapeBorder.lerp(stadium, circle, 0.9), 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 82.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
|
||||
expect(ShapeBorder.lerp(circle, stadium, 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 10.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(circle, stadium, 0.8).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 20.0% of the way to being a CircleBorder)');
|
||||
expect(ShapeBorder.lerp(ShapeBorder.lerp(stadium, circle, 0.9), ShapeBorder.lerp(stadium, circle, 0.1), 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 82.0% of the way to being a CircleBorder)');
|
||||
expect(
|
||||
ShapeBorder.lerp(circle, stadium, 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 10.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(circle, stadium, 0.8).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 20.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(ShapeBorder.lerp(stadium, circle, 0.9), ShapeBorder.lerp(stadium, circle, 0.1), 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 82.0% of the way to being a CircleBorder)',
|
||||
);
|
||||
|
||||
expect(ShapeBorder.lerp(stadium, circle, 0.1), ShapeBorder.lerp(stadium, circle, 0.1));
|
||||
expect(ShapeBorder.lerp(stadium, circle, 0.1).hashCode, ShapeBorder.lerp(stadium, circle, 0.1).hashCode);
|
||||
@ -141,25 +153,37 @@ void main() {
|
||||
expect(ShapeBorder.lerp(rrect, ShapeBorder.lerp(stadium, rrect, 0.1), 0.1)!.getOuterPath(rect), looksLikeS);
|
||||
expect(ShapeBorder.lerp(rrect, ShapeBorder.lerp(stadium, rrect, 0.1), 0.9)!.getOuterPath(rect), looksLikeS);
|
||||
|
||||
expect(ShapeBorder.lerp(stadium, rrect, 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 10.0% of the way to being a RoundedRectangleBorder)');
|
||||
expect(ShapeBorder.lerp(stadium, rrect, 0.2).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 20.0% of the way to being a RoundedRectangleBorder)');
|
||||
expect(ShapeBorder.lerp(ShapeBorder.lerp(stadium, rrect, 0.1), ShapeBorder.lerp(stadium, rrect, 0.9), 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 82.0% of the way to being a RoundedRectangleBorder)');
|
||||
expect(
|
||||
ShapeBorder.lerp(stadium, rrect, 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 10.0% of the way to being a RoundedRectangleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(stadium, rrect, 0.2).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 20.0% of the way to being a RoundedRectangleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(ShapeBorder.lerp(stadium, rrect, 0.1), ShapeBorder.lerp(stadium, rrect, 0.9), 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 82.0% of the way to being a RoundedRectangleBorder)',
|
||||
);
|
||||
|
||||
expect(ShapeBorder.lerp(rrect, stadium, 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 10.0% of the way to being a RoundedRectangleBorder)');
|
||||
expect(ShapeBorder.lerp(rrect, stadium, 0.8).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 20.0% of the way to being a RoundedRectangleBorder)');
|
||||
expect(ShapeBorder.lerp(ShapeBorder.lerp(stadium, rrect, 0.9), ShapeBorder.lerp(stadium, rrect, 0.1), 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 82.0% of the way to being a RoundedRectangleBorder)');
|
||||
expect(
|
||||
ShapeBorder.lerp(rrect, stadium, 0.9).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 10.0% of the way to being a RoundedRectangleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(rrect, stadium, 0.8).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 20.0% of the way to being a RoundedRectangleBorder)',
|
||||
);
|
||||
expect(
|
||||
ShapeBorder.lerp(ShapeBorder.lerp(stadium, rrect, 0.9), ShapeBorder.lerp(stadium, rrect, 0.1), 0.1).toString(),
|
||||
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
|
||||
'BorderRadius.zero, 82.0% of the way to being a RoundedRectangleBorder)',
|
||||
);
|
||||
|
||||
expect(ShapeBorder.lerp(stadium, rrect, 0.1), ShapeBorder.lerp(stadium, rrect, 0.1));
|
||||
expect(ShapeBorder.lerp(stadium, rrect, 0.1).hashCode, ShapeBorder.lerp(stadium, rrect, 0.1).hashCode);
|
||||
|
@ -72,7 +72,7 @@ void main() {
|
||||
' TextSpan:\n'
|
||||
' (empty)\n'
|
||||
' TextSpan:\n'
|
||||
' "c"\n'
|
||||
' "c"\n',
|
||||
));
|
||||
});
|
||||
|
||||
@ -82,7 +82,7 @@ void main() {
|
||||
);
|
||||
expect(test1.toStringDeep(), equals(
|
||||
'TextSpan:\n'
|
||||
' "a"\n'
|
||||
' "a"\n',
|
||||
));
|
||||
|
||||
final TextSpan test2 = TextSpan(
|
||||
@ -95,7 +95,7 @@ void main() {
|
||||
'TextSpan:\n'
|
||||
' "a"\n'
|
||||
' callbacks: enter, exit\n'
|
||||
' mouseCursor: SystemMouseCursor(forbidden)\n'
|
||||
' mouseCursor: SystemMouseCursor(forbidden)\n',
|
||||
));
|
||||
});
|
||||
|
||||
@ -335,7 +335,7 @@ void main() {
|
||||
},
|
||||
onExit: (PointerExitEvent event) {
|
||||
logEvents.add(event);
|
||||
}
|
||||
},
|
||||
),
|
||||
const TextSpan(
|
||||
text: 'xxxxx',
|
||||
|
@ -43,8 +43,7 @@ void main() {
|
||||
// Verify that the "through" FrictionSimulation ends up at
|
||||
// endPosition and endVelocity; implies that it computed the right
|
||||
// value for _drag.
|
||||
FrictionSimulation friction = FrictionSimulation.through(
|
||||
startPosition, endPosition, startVelocity, endVelocity);
|
||||
FrictionSimulation friction = FrictionSimulation.through(startPosition, endPosition, startVelocity, endVelocity);
|
||||
expect(friction.isDone(0.0), false);
|
||||
expect(friction.x(0.0), 10.0);
|
||||
expect(friction.dx(0.0), 600.0);
|
||||
@ -63,8 +62,7 @@ void main() {
|
||||
expect(endPosition, lessThan(startPosition));
|
||||
expect(endVelocity, greaterThan(startVelocity));
|
||||
|
||||
friction = FrictionSimulation.through(
|
||||
startPosition, endPosition, startVelocity, endVelocity);
|
||||
friction = FrictionSimulation.through(startPosition, endPosition, startVelocity, endVelocity);
|
||||
expect(friction.isDone(1.0 + precisionErrorTolerance), true);
|
||||
expect(friction.x(1.0), moreOrLessEquals(endPosition));
|
||||
expect(friction.dx(1.0), moreOrLessEquals(endVelocity));
|
||||
@ -116,31 +114,47 @@ void main() {
|
||||
|
||||
test('spring_types', () {
|
||||
SpringSimulation crit = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0), 0.0, 300.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
), 0.0, 300.0, 0.0);
|
||||
expect(crit.type, SpringType.criticallyDamped);
|
||||
|
||||
crit = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0, ratio: 1.0), 0.0, 300.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
ratio: 1.0,
|
||||
), 0.0, 300.0, 0.0);
|
||||
expect(crit.type, SpringType.criticallyDamped);
|
||||
|
||||
final SpringSimulation under = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0, ratio: 0.75), 0.0, 300.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
ratio: 0.75,
|
||||
), 0.0, 300.0, 0.0);
|
||||
expect(under.type, SpringType.underDamped);
|
||||
|
||||
final SpringSimulation over = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0, ratio: 1.25), 0.0, 300.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
ratio: 1.25,
|
||||
), 0.0, 300.0, 0.0);
|
||||
expect(over.type, SpringType.overDamped);
|
||||
|
||||
// Just so we don't forget how to create a desc without the ratio.
|
||||
final SpringSimulation other = SpringSimulation(
|
||||
const SpringDescription(mass: 1.0, stiffness: 100.0, damping: 20.0),
|
||||
0.0, 20.0, 20.0);
|
||||
final SpringSimulation other = SpringSimulation(const SpringDescription(
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
damping: 20.0,
|
||||
), 0.0, 20.0, 20.0);
|
||||
expect(other.type, SpringType.criticallyDamped);
|
||||
});
|
||||
|
||||
test('crit_spring', () {
|
||||
final SpringSimulation crit = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0, ratio: 1.0), 0.0, 500.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
ratio: 1.0,
|
||||
), 0.0, 500.0, 0.0);
|
||||
|
||||
crit.tolerance = const Tolerance(distance: 0.01, velocity: 0.01);
|
||||
|
||||
@ -165,7 +179,10 @@ void main() {
|
||||
|
||||
test('overdamped_spring', () {
|
||||
final SpringSimulation over = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0, ratio: 1.25), 0.0, 500.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
ratio: 1.25,
|
||||
), 0.0, 500.0, 0.0);
|
||||
|
||||
over.tolerance = const Tolerance(distance: 0.01, velocity: 0.01);
|
||||
|
||||
@ -187,7 +204,10 @@ void main() {
|
||||
|
||||
test('underdamped_spring', () {
|
||||
final SpringSimulation under = SpringSimulation(SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 100.0, ratio: 0.25), 0.0, 300.0, 0.0);
|
||||
mass: 1.0,
|
||||
stiffness: 100.0,
|
||||
ratio: 0.25,
|
||||
), 0.0, 300.0, 0.0);
|
||||
expect(under.type, SpringType.underDamped);
|
||||
|
||||
expect(under.isDone(0.0), false);
|
||||
@ -204,7 +224,10 @@ void main() {
|
||||
|
||||
test('test_kinetic_scroll', () {
|
||||
final SpringDescription spring = SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 50.0, ratio: 0.5);
|
||||
mass: 1.0,
|
||||
stiffness: 50.0,
|
||||
ratio: 0.5,
|
||||
);
|
||||
|
||||
final BouncingScrollSimulation scroll = BouncingScrollSimulation(
|
||||
position: 100.0,
|
||||
@ -233,7 +256,10 @@ void main() {
|
||||
|
||||
test('scroll_with_inf_edge_ends', () {
|
||||
final SpringDescription spring = SpringDescription.withDampingRatio(
|
||||
mass: 1.0, stiffness: 50.0, ratio: 0.5);
|
||||
mass: 1.0,
|
||||
stiffness: 50.0,
|
||||
ratio: 0.5,
|
||||
);
|
||||
|
||||
final BouncingScrollSimulation scroll = BouncingScrollSimulation(
|
||||
position: 100.0,
|
||||
|
@ -39,34 +39,36 @@ void main() {
|
||||
});
|
||||
|
||||
test('test pumpBenchmark() only runs one frame', () async {
|
||||
await benchmarkWidgets((WidgetTester tester) async {
|
||||
const Key root = Key('root');
|
||||
binding.attachRootWidget(Container(key: root));
|
||||
await tester.pump();
|
||||
await benchmarkWidgets(
|
||||
(WidgetTester tester) async {
|
||||
const Key root = Key('root');
|
||||
binding.attachRootWidget(Container(key: root));
|
||||
await tester.pump();
|
||||
|
||||
expect(binding.framesBegun, greaterThan(0));
|
||||
expect(binding.framesDrawn, greaterThan(0));
|
||||
expect(binding.framesBegun, greaterThan(0));
|
||||
expect(binding.framesDrawn, greaterThan(0));
|
||||
|
||||
final Element appState = tester.element(find.byKey(root));
|
||||
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.benchmark;
|
||||
final Element appState = tester.element(find.byKey(root));
|
||||
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.benchmark;
|
||||
|
||||
final int startFramesBegun = binding.framesBegun;
|
||||
final int startFramesDrawn = binding.framesDrawn;
|
||||
expect(startFramesBegun, equals(startFramesDrawn));
|
||||
final int startFramesBegun = binding.framesBegun;
|
||||
final int startFramesDrawn = binding.framesDrawn;
|
||||
expect(startFramesBegun, equals(startFramesDrawn));
|
||||
|
||||
appState.markNeedsBuild();
|
||||
appState.markNeedsBuild();
|
||||
|
||||
await tester.pumpBenchmark(const Duration(milliseconds: 16));
|
||||
await tester.pumpBenchmark(const Duration(milliseconds: 16));
|
||||
|
||||
final int endFramesBegun = binding.framesBegun;
|
||||
final int endFramesDrawn = binding.framesDrawn;
|
||||
expect(endFramesBegun, equals(endFramesDrawn));
|
||||
final int endFramesBegun = binding.framesBegun;
|
||||
final int endFramesDrawn = binding.framesDrawn;
|
||||
expect(endFramesBegun, equals(endFramesDrawn));
|
||||
|
||||
expect(endFramesBegun, equals(startFramesBegun + 1));
|
||||
expect(endFramesDrawn, equals(startFramesDrawn + 1));
|
||||
},
|
||||
// We are not interested in the performance of the "benchmark", we are just
|
||||
// testing the behavior. So it's OK that asserts are enabled.
|
||||
mayRunWithAsserts: true);
|
||||
expect(endFramesBegun, equals(startFramesBegun + 1));
|
||||
expect(endFramesDrawn, equals(startFramesDrawn + 1));
|
||||
},
|
||||
// We are not interested in the performance of the "benchmark", we are just
|
||||
// testing the behavior. So it's OK that asserts are enabled.
|
||||
mayRunWithAsserts: true,
|
||||
);
|
||||
}, skip: isBrowser);
|
||||
}
|
||||
|
@ -82,9 +82,10 @@ void main() {
|
||||
childrenInInversePaintOrder: children,
|
||||
);
|
||||
|
||||
children.add(SemanticsNode()
|
||||
..isMergedIntoParent = true
|
||||
..rect = const Rect.fromLTRB(42.0, 42.0, 10.0, 10.0)
|
||||
children.add(
|
||||
SemanticsNode()
|
||||
..isMergedIntoParent = true
|
||||
..rect = const Rect.fromLTRB(42.0, 42.0, 10.0, 10.0),
|
||||
);
|
||||
|
||||
{
|
||||
@ -101,7 +102,7 @@ void main() {
|
||||
'Failed to replace child semantics nodes because the list of `SemanticsNode`s was mutated.\n'
|
||||
'Instead of mutating the existing list, create a new list containing the desired `SemanticsNode`s.\n'
|
||||
'Error details:\n'
|
||||
"The list's length has changed from 1 to 2."
|
||||
"The list's length has changed from 1 to 2.",
|
||||
));
|
||||
expect(
|
||||
error.diagnostics.singleWhere((DiagnosticsNode node) => node.level == DiagnosticLevel.hint).toString(),
|
||||
@ -150,7 +151,7 @@ void main() {
|
||||
'\n'
|
||||
' Child node at position 1 was replaced:\n'
|
||||
' Previous child: SemanticsNode#7(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(40.0, 14.0, 20.0, 20.0))\n'
|
||||
' New child: SemanticsNode#5(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(10.0, 10.0, 20.0, 20.0))\n'
|
||||
' New child: SemanticsNode#5(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(10.0, 10.0, 20.0, 20.0))\n',
|
||||
));
|
||||
|
||||
expect(
|
||||
@ -489,16 +490,16 @@ void main() {
|
||||
expect(
|
||||
allProperties.toStringDeep(),
|
||||
equalsIgnoringHashCodes(
|
||||
'SemanticsNode#2\n'
|
||||
' STALE\n'
|
||||
' owner: null\n'
|
||||
' merge boundary ⛔️\n'
|
||||
' Rect.fromLTRB(60.0, 20.0, 80.0, 50.0)\n'
|
||||
' actions: longPress, scrollUp, showOnScreen\n'
|
||||
' flags: hasCheckedState, isSelected, isButton\n'
|
||||
' label: "Use all the properties"\n'
|
||||
' textDirection: rtl\n'
|
||||
' sortKey: OrdinalSortKey#19df5(order: 1.0)\n'
|
||||
'SemanticsNode#2\n'
|
||||
' STALE\n'
|
||||
' owner: null\n'
|
||||
' merge boundary ⛔️\n'
|
||||
' Rect.fromLTRB(60.0, 20.0, 80.0, 50.0)\n'
|
||||
' actions: longPress, scrollUp, showOnScreen\n'
|
||||
' flags: hasCheckedState, isSelected, isButton\n'
|
||||
' label: "Use all the properties"\n'
|
||||
' textDirection: rtl\n'
|
||||
' sortKey: OrdinalSortKey#19df5(order: 1.0)\n',
|
||||
),
|
||||
);
|
||||
expect(
|
||||
|
@ -18,7 +18,7 @@ void main() {
|
||||
const Placeholder(),
|
||||
// Stops right after the warm up frame.
|
||||
null,
|
||||
EnginePhase.build
|
||||
EnginePhase.build,
|
||||
);
|
||||
// The warm up frame will send update for an empty semantics tree. We
|
||||
// ignore this one time update.
|
||||
|
Loading…
x
Reference in New Issue
Block a user