Add missing properties to _ArcPaintPredicate. (#162572)
Fixes https://github.com/flutter/flutter/issues/162317 ### Description - Adds `startAngle`, `sweepAngle` and `useCenter` properties to `_ArcPaintPredicate` - Adds tests for `_ArcPaintPredicate` ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
This commit is contained in:
parent
7e81af2b45
commit
c12330fd21
@ -388,6 +388,9 @@ abstract class PaintPattern {
|
|||||||
/// arguments as they were seen by the method.
|
/// arguments as they were seen by the method.
|
||||||
void arc({
|
void arc({
|
||||||
Rect? rect,
|
Rect? rect,
|
||||||
|
double? startAngle,
|
||||||
|
double? sweepAngle,
|
||||||
|
bool? useCenter,
|
||||||
Color? color,
|
Color? color,
|
||||||
double? strokeWidth,
|
double? strokeWidth,
|
||||||
bool? hasMaskFilter,
|
bool? hasMaskFilter,
|
||||||
@ -968,6 +971,9 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher
|
|||||||
@override
|
@override
|
||||||
void arc({
|
void arc({
|
||||||
Rect? rect,
|
Rect? rect,
|
||||||
|
double? startAngle,
|
||||||
|
double? sweepAngle,
|
||||||
|
bool? useCenter,
|
||||||
Color? color,
|
Color? color,
|
||||||
double? strokeWidth,
|
double? strokeWidth,
|
||||||
bool? hasMaskFilter,
|
bool? hasMaskFilter,
|
||||||
@ -977,6 +983,9 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher
|
|||||||
_predicates.add(
|
_predicates.add(
|
||||||
_ArcPaintPredicate(
|
_ArcPaintPredicate(
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
startAngle: startAngle,
|
||||||
|
sweepAngle: sweepAngle,
|
||||||
|
useCenter: useCenter,
|
||||||
color: color,
|
color: color,
|
||||||
strokeWidth: strokeWidth,
|
strokeWidth: strokeWidth,
|
||||||
hasMaskFilter: hasMaskFilter,
|
hasMaskFilter: hasMaskFilter,
|
||||||
@ -1598,6 +1607,9 @@ class _LinePaintPredicate extends _DrawCommandPaintPredicate {
|
|||||||
class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
|
class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
|
||||||
_ArcPaintPredicate({
|
_ArcPaintPredicate({
|
||||||
this.rect,
|
this.rect,
|
||||||
|
this.startAngle,
|
||||||
|
this.sweepAngle,
|
||||||
|
this.useCenter,
|
||||||
super.color,
|
super.color,
|
||||||
super.strokeWidth,
|
super.strokeWidth,
|
||||||
super.hasMaskFilter,
|
super.hasMaskFilter,
|
||||||
@ -1607,6 +1619,12 @@ class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
|
|||||||
|
|
||||||
final Rect? rect;
|
final Rect? rect;
|
||||||
|
|
||||||
|
final double? startAngle;
|
||||||
|
|
||||||
|
final double? sweepAngle;
|
||||||
|
|
||||||
|
final bool? useCenter;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void verifyArguments(List<dynamic> arguments) {
|
void verifyArguments(List<dynamic> arguments) {
|
||||||
super.verifyArguments(arguments);
|
super.verifyArguments(arguments);
|
||||||
@ -1617,6 +1635,27 @@ class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
|
|||||||
'exactly the expected rect ($rect).',
|
'exactly the expected rect ($rect).',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
final double startAngleArgument = arguments[1] as double;
|
||||||
|
if (startAngle != null && startAngleArgument != startAngle) {
|
||||||
|
throw FlutterError(
|
||||||
|
'It called $methodName with a start angle, $startAngleArgument, which '
|
||||||
|
'was not exactly the expected start angle ($startAngle).',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final double sweepAngleArgument = arguments[2] as double;
|
||||||
|
if (sweepAngle != null && sweepAngleArgument != sweepAngle) {
|
||||||
|
throw FlutterError(
|
||||||
|
'It called $methodName with a sweep angle, $sweepAngleArgument, which '
|
||||||
|
'was not exactly the expected sweep angle ($sweepAngle).',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final bool useCenterArgument = arguments[3] as bool;
|
||||||
|
if (useCenter != null && useCenterArgument != useCenter) {
|
||||||
|
throw FlutterError(
|
||||||
|
'It called $methodName with a useCenter value, $useCenterArgument, '
|
||||||
|
'which was not exactly the expected value ($useCenter).',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1625,6 +1664,15 @@ class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
|
|||||||
if (rect != null) {
|
if (rect != null) {
|
||||||
description.add('rect $rect');
|
description.add('rect $rect');
|
||||||
}
|
}
|
||||||
|
if (startAngle != null) {
|
||||||
|
description.add('startAngle $startAngle');
|
||||||
|
}
|
||||||
|
if (sweepAngle != null) {
|
||||||
|
description.add('sweepAngle $sweepAngle');
|
||||||
|
}
|
||||||
|
if (useCenter != null) {
|
||||||
|
description.add('useCenter $useCenter');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
@ -220,4 +222,160 @@ void main() {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('arc', () {
|
||||||
|
final Rect rect = Offset.zero & const Size.square(50);
|
||||||
|
const double startAngle = math.pi / 4;
|
||||||
|
const double sweepAngle = math.pi / 2;
|
||||||
|
const bool useCenter = false;
|
||||||
|
final Paint paint = Paint()..color = Colors.blue;
|
||||||
|
|
||||||
|
Future<void> pumpPainter(WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Center(
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: _ArcPainter(
|
||||||
|
startAngle: startAngle,
|
||||||
|
sweepAngle: sweepAngle,
|
||||||
|
useCenter: useCenter,
|
||||||
|
paint: paint,
|
||||||
|
),
|
||||||
|
size: rect.size,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
testWidgets('matches when rect is correct', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
expect(tester.renderObject(find.byType(CustomPaint)), paints..arc(rect: rect));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('does not match when rect is incorrect', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() => expect(
|
||||||
|
tester.renderObject(find.byType(CustomPaint)),
|
||||||
|
paints..arc(rect: rect.deflate(10)),
|
||||||
|
),
|
||||||
|
throwsA(
|
||||||
|
isA<TestFailure>().having(
|
||||||
|
(TestFailure failure) => failure.message,
|
||||||
|
'message',
|
||||||
|
contains(
|
||||||
|
'It called drawArc with a paint whose rect, '
|
||||||
|
'Rect.fromLTRB(0.0, 0.0, 50.0, 50.0), was not exactly the '
|
||||||
|
'expected rect (Rect.fromLTRB(10.0, 10.0, 40.0, 40.0)).',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('matches when startAngle is correct', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
expect(tester.renderObject(find.byType(CustomPaint)), paints..arc(startAngle: startAngle));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('does not match when startAngle is incorrect', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() => expect(
|
||||||
|
tester.renderObject(find.byType(CustomPaint)),
|
||||||
|
paints..arc(startAngle: startAngle * 2),
|
||||||
|
),
|
||||||
|
throwsA(
|
||||||
|
isA<TestFailure>().having(
|
||||||
|
(TestFailure failure) => failure.message,
|
||||||
|
'message',
|
||||||
|
contains(
|
||||||
|
'It called drawArc with a start angle, 0.7853981633974483, which '
|
||||||
|
'was not exactly the expected start angle (1.5707963267948966).',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('matches when sweepAngle is correct', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
expect(tester.renderObject(find.byType(CustomPaint)), paints..arc(sweepAngle: sweepAngle));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('does not match when sweepAngle is incorrect', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() => expect(
|
||||||
|
tester.renderObject(find.byType(CustomPaint)),
|
||||||
|
paints..arc(sweepAngle: sweepAngle * 2),
|
||||||
|
),
|
||||||
|
throwsA(
|
||||||
|
isA<TestFailure>().having(
|
||||||
|
(TestFailure failure) => failure.message,
|
||||||
|
'message',
|
||||||
|
contains(
|
||||||
|
'It called drawArc with a sweep angle, 1.5707963267948966, which '
|
||||||
|
'was not exactly the expected sweep angle (3.141592653589793).',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('matches when useCenter is correct', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
expect(tester.renderObject(find.byType(CustomPaint)), paints..arc(useCenter: useCenter));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('does not match when useCenter is incorrect', (WidgetTester tester) async {
|
||||||
|
await pumpPainter(tester);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() => expect(
|
||||||
|
tester.renderObject(find.byType(CustomPaint)),
|
||||||
|
paints..arc(useCenter: !useCenter),
|
||||||
|
),
|
||||||
|
throwsA(
|
||||||
|
isA<TestFailure>().having(
|
||||||
|
(TestFailure failure) => failure.message,
|
||||||
|
'message',
|
||||||
|
contains(
|
||||||
|
'It called drawArc with a useCenter value, false, which was not '
|
||||||
|
'exactly the expected value (true)',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ArcPainter extends CustomPainter {
|
||||||
|
const _ArcPainter({
|
||||||
|
required this.startAngle,
|
||||||
|
required this.sweepAngle,
|
||||||
|
required this.useCenter,
|
||||||
|
required Paint paint,
|
||||||
|
}) : _paint = paint;
|
||||||
|
|
||||||
|
final double startAngle;
|
||||||
|
|
||||||
|
final double sweepAngle;
|
||||||
|
|
||||||
|
final bool useCenter;
|
||||||
|
|
||||||
|
final Paint _paint;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
canvas.drawArc(Offset.zero & size, startAngle, sweepAngle, useCenter, _paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(MyPainter oldDelegate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user