341 lines
11 KiB
Dart
341 lines
11 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// This file is run as part of a reduced test set in CI on Mac and Windows
|
|
// machines.
|
|
@Tags(<String>['reduced-test-set'])
|
|
library;
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
class _FilterTest extends StatelessWidget {
|
|
const _FilterTest(Widget child, {this.brightness = Brightness.light}) : _child = child;
|
|
final Brightness brightness;
|
|
final Widget _child;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final Size size = MediaQuery.sizeOf(context);
|
|
final double tileHeight = size.height / 4;
|
|
final double tileWidth = size.width / 8;
|
|
return CupertinoApp(
|
|
home: Stack(
|
|
fit: StackFit.expand,
|
|
children: <Widget>[
|
|
// 512 color tiles
|
|
// 4 alpha levels (0.416, 0.25, 0.5, 0.75)
|
|
for (int a = 0; a < 4; a++)
|
|
for (int h = 0; h < 8; h++) // 8 hues
|
|
for (int s = 0; s < 4; s++) // 4 saturation levels
|
|
for (int b = 0; b < 4; b++) // 4 brightness levels
|
|
Positioned(
|
|
left: h * tileWidth + b * tileWidth / 4,
|
|
top: a * tileHeight + s * tileHeight / 4,
|
|
height: tileHeight,
|
|
width: tileWidth,
|
|
child: ColoredBox(
|
|
color: HSVColor.fromAHSV(
|
|
0.5 + a / 8,
|
|
h * 45,
|
|
0.5 + s / 8,
|
|
0.5 + b / 8,
|
|
).toColor(),
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.all(32),
|
|
child: CupertinoTheme(
|
|
data: CupertinoThemeData(brightness: brightness),
|
|
child: _child,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
void disableVibranceForTest() {
|
|
CupertinoPopupSurface.debugIsVibrancePainted = false;
|
|
addTearDown(() {
|
|
CupertinoPopupSurface.debugIsVibrancePainted = true;
|
|
});
|
|
}
|
|
|
|
// Golden displays the color filter effect of the CupertinoPopupSurface
|
|
// when the ambient brightness is light.
|
|
testWidgets(
|
|
'Brightness.light color filter',
|
|
(WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(blurSigma: 0, isSurfacePainted: false, child: SizedBox()),
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.color-filter.light.png'),
|
|
);
|
|
},
|
|
skip: kIsWasm, // https://github.com/flutter/flutter/issues/152026
|
|
);
|
|
|
|
// Golden displays the color filter effect of the CupertinoPopupSurface
|
|
// when the ambient brightness is dark.
|
|
testWidgets(
|
|
'Brightness.dark color filter',
|
|
(WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(blurSigma: 0, isSurfacePainted: false, child: SizedBox()),
|
|
brightness: Brightness.dark,
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.color-filter.dark.png'),
|
|
);
|
|
},
|
|
skip: kIsWasm, // https://github.com/flutter/flutter/issues/152026
|
|
);
|
|
|
|
// Golden displays color tiles without CupertinoPopupSurface being
|
|
// displayed.
|
|
testWidgets('Setting debugIsVibrancePainted to false removes the color filter', (
|
|
WidgetTester tester,
|
|
) async {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(blurSigma: 0, isSurfacePainted: false, child: SizedBox()),
|
|
),
|
|
);
|
|
|
|
// The BackdropFilter widget should not be mounted when blurSigma is 0 and
|
|
// CupertinoPopupSurface.debugIsVibrancePainted is false.
|
|
expect(
|
|
find.descendant(
|
|
of: find.byType(CupertinoPopupSurface),
|
|
matching: find.byType(BackdropFilter),
|
|
),
|
|
findsNothing,
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.color-filter.removed.png'),
|
|
);
|
|
});
|
|
|
|
// Golden displays the surface color of the CupertinoPopupSurface
|
|
// in light mode.
|
|
testWidgets('Brightness.light surface color', (WidgetTester tester) async {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(CupertinoPopupSurface(blurSigma: 0, child: SizedBox())),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.surface-color.light.png'),
|
|
);
|
|
});
|
|
|
|
// Golden displays the surface color of the CupertinoPopupSurface
|
|
// in dark mode.
|
|
testWidgets('Brightness.dark surface color', (WidgetTester tester) async {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(blurSigma: 0, child: SizedBox()),
|
|
brightness: Brightness.dark,
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.surface-color.dark.png'),
|
|
);
|
|
});
|
|
|
|
// Golden displays a CupertinoPopupSurface with the color removed. The result
|
|
// should only display color tiles.
|
|
testWidgets('Setting isSurfacePainted to false removes the surface color', (
|
|
WidgetTester tester,
|
|
) async {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(blurSigma: 0, isSurfacePainted: false, child: SizedBox()),
|
|
brightness: Brightness.dark,
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.surface-color.removed.png'),
|
|
);
|
|
});
|
|
|
|
// Goldens display a CupertinoPopupSurface with no vibrance or surface
|
|
// color, with blur sigmas of 5 and 30 (default).
|
|
testWidgets(
|
|
'Positive blurSigma applies blur',
|
|
(WidgetTester tester) async {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(isSurfacePainted: false, blurSigma: 5, child: SizedBox()),
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.blur.5.png'),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
const _FilterTest(CupertinoPopupSurface(isSurfacePainted: false, child: SizedBox())),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
// 30 is the default blur sigma
|
|
matchesGoldenFile('cupertinoPopupSurface.blur.30.png'),
|
|
);
|
|
},
|
|
skip: kIsWasm, // https://github.com/flutter/flutter/issues/152026
|
|
);
|
|
|
|
// Golden displays a CupertinoPopupSurface with a blur sigma of 0. Because
|
|
// the blur sigma is 0 and vibrance and surface are not painted, no popup
|
|
// surface is displayed.
|
|
testWidgets('Setting blurSigma to zero removes blur', (WidgetTester tester) async {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(isSurfacePainted: false, blurSigma: 0, child: SizedBox()),
|
|
),
|
|
);
|
|
|
|
// The BackdropFilter widget should not be mounted when blurSigma is 0 and
|
|
// CupertinoPopupSurface.isVibrancePainted is false.
|
|
expect(
|
|
find.descendant(
|
|
of: find.byType(CupertinoPopupSurface),
|
|
matching: find.byType(BackdropFilter),
|
|
),
|
|
findsNothing,
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.blur.0.png'),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
CupertinoPopupSurface(isSurfacePainted: false, blurSigma: 0, child: SizedBox()),
|
|
),
|
|
);
|
|
});
|
|
|
|
testWidgets('Setting a blurSigma to a negative number throws', (WidgetTester tester) async {
|
|
try {
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
_FilterTest(
|
|
CupertinoPopupSurface(isSurfacePainted: false, blurSigma: -1, child: const SizedBox()),
|
|
),
|
|
);
|
|
|
|
fail('CupertinoPopupSurface did not throw when provided a negative blur sigma.');
|
|
} on AssertionError catch (error) {
|
|
expect(
|
|
error.toString(),
|
|
contains('CupertinoPopupSurface requires a non-negative blur sigma.'),
|
|
);
|
|
}
|
|
});
|
|
|
|
// Regression test for https://github.com/flutter/flutter/issues/154887.
|
|
testWidgets(
|
|
"Applying a FadeTransition to the CupertinoPopupSurface doesn't cause transparency",
|
|
(WidgetTester tester) async {
|
|
final controller = AnimationController(
|
|
duration: const Duration(milliseconds: 100),
|
|
vsync: const TestVSync(),
|
|
);
|
|
addTearDown(controller.dispose);
|
|
controller.forward();
|
|
|
|
await tester.pumpWidget(
|
|
_FilterTest(
|
|
FadeTransition(
|
|
opacity: controller,
|
|
child: const CupertinoPopupSurface(child: SizedBox()),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pump(const Duration(milliseconds: 50));
|
|
|
|
// Golden should display a CupertinoPopupSurface with no transparency
|
|
// directly underneath the surface. A small amount of transparency should be
|
|
// present on the upper-left corner of the screen.
|
|
//
|
|
// If transparency (gray and white grid) is present underneath the surface,
|
|
// the blendmode is being incorrectly applied.
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.blendmode-fix.0.png'),
|
|
);
|
|
|
|
await tester.pumpAndSettle();
|
|
},
|
|
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
|
);
|
|
|
|
// Golden displays a CupertinoPopupSurface with all enabled features.
|
|
//
|
|
// CupertinoPopupSurface uses ImageFilter.compose, which applies an inner
|
|
// filter first, followed by an outer filter (e.g. result =
|
|
// outer(inner(source))).
|
|
//
|
|
// For CupertinoPopupSurface, this means that the pixels underlying the
|
|
// surface are first saturated with a ColorFilter, and the resulting saturated
|
|
// pixels are blurred with an ImageFilter.blur. This test verifies that this
|
|
// order does not change.
|
|
testWidgets('Saturation is applied before blur', (WidgetTester tester) async {
|
|
await tester.pumpWidget(const _FilterTest(CupertinoPopupSurface(child: SizedBox())));
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.composition.png'),
|
|
);
|
|
|
|
disableVibranceForTest();
|
|
await tester.pumpWidget(
|
|
const _FilterTest(
|
|
Stack(
|
|
fit: StackFit.expand,
|
|
children: <Widget>[
|
|
CupertinoPopupSurface(isSurfacePainted: false, blurSigma: 0, child: SizedBox()),
|
|
CupertinoPopupSurface(child: SizedBox()),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byType(CupertinoApp),
|
|
matchesGoldenFile('cupertinoPopupSurface.composition.png'),
|
|
);
|
|
});
|
|
}
|