Skip to content

Commit 05de81e

Browse files
authored
Add drawRSuperellipse support to mock_canvas. (#165744)
Closes flutter/flutter#165743 ### Description - Adds `rsuperellipse` to `mock_canvas.dart` to verify `drawRSuperellipse` calls - Adds tests for `paints..rsuperellipse` ## 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. - [X] 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.
1 parent 713d906 commit 05de81e

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

packages/flutter_test/lib/src/mock_canvas.dart

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,30 @@ abstract class PaintPattern {
289289
PaintingStyle style,
290290
});
291291

292+
/// Indicates that a rounded superellipse is expected next.
293+
///
294+
/// The next rounded superellipse is examined. Any arguments that are passed
295+
/// to this method are compared to the actual [Canvas.drawRSuperellipse]
296+
/// call's arguments and any mismatches result in failure.
297+
///
298+
/// If no call to [Canvas.drawRSuperellipse] was made, then this results in
299+
/// failure.
300+
///
301+
/// Any calls made between the last matched call (if any) and the
302+
/// [Canvas.drawRSuperellipse] call are ignored.
303+
///
304+
/// The [Paint]-related arguments (`color`, `strokeWidth`, `hasMaskFilter`)
305+
/// are compared against the state of the [Paint] object after the
306+
/// painting has completed, not at the time of the call. If the same [Paint]
307+
/// object is reused multiple times, then this may not match the actual
308+
/// arguments as they were seen by the method.
309+
void rsuperellipse({
310+
RSuperellipse? rsuperellipse,
311+
Color? color,
312+
double? strokeWidth,
313+
bool? hasMaskFilter,
314+
});
315+
292316
/// Indicates that a rounded superellipse clip is expected next.
293317
///
294318
/// The next rounded superellipse clip is examined. Any arguments that are
@@ -916,6 +940,23 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher
916940
);
917941
}
918942

943+
@override
944+
void rsuperellipse({
945+
RSuperellipse? rsuperellipse,
946+
Color? color,
947+
double? strokeWidth,
948+
bool? hasMaskFilter,
949+
}) {
950+
_predicates.add(
951+
_RSuperellipsePaintPredicate(
952+
rsuperellipse: rsuperellipse,
953+
color: color,
954+
strokeWidth: strokeWidth,
955+
hasMaskFilter: hasMaskFilter,
956+
),
957+
);
958+
}
959+
919960
@override
920961
void clipRSuperellipse({RSuperellipse? rsuperellipse}) {
921962
_predicates.add(_FunctionPaintPredicate(#clipRSuperellipse, <dynamic>[rsuperellipse]));
@@ -1450,6 +1491,38 @@ class _DRRectPaintPredicate extends _TwoParameterPaintPredicate<RRect, RRect> {
14501491
}) : super(#drawDRRect, 'a rounded rectangle outline', expected1: outer, expected2: inner);
14511492
}
14521493

1494+
class _RSuperellipsePaintPredicate extends _DrawCommandPaintPredicate {
1495+
_RSuperellipsePaintPredicate({
1496+
this.rsuperellipse,
1497+
super.color,
1498+
super.strokeWidth,
1499+
super.hasMaskFilter,
1500+
}) : super(#drawRSuperellipse, 'a rounded superellipse', 2, 1);
1501+
1502+
final RSuperellipse? rsuperellipse;
1503+
1504+
@override
1505+
void verifyArguments(List<dynamic> arguments) {
1506+
super.verifyArguments(arguments);
1507+
final RSuperellipse rsuperellipseArgument = arguments[0] as RSuperellipse;
1508+
if (rsuperellipse != null && rsuperellipseArgument != rsuperellipse) {
1509+
throw FlutterError(
1510+
'It called $methodName with a rounded superellipse, '
1511+
'$rsuperellipseArgument, which was not exactly the expected rounded '
1512+
'superellipse ($rsuperellipse).',
1513+
);
1514+
}
1515+
}
1516+
1517+
@override
1518+
void debugFillDescription(List<String> description) {
1519+
super.debugFillDescription(description);
1520+
if (rsuperellipse != null) {
1521+
description.add('rounded superellipse $rsuperellipse');
1522+
}
1523+
}
1524+
}
1525+
14531526
class _CirclePaintPredicate extends _DrawCommandPaintPredicate {
14541527
_CirclePaintPredicate({
14551528
this.x,

packages/flutter_test/test/mock_canvas_test.dart

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,56 @@ void main() {
351351
);
352352
});
353353
});
354+
355+
group('rsuperellipse', () {
356+
final RSuperellipse rsuperellipse = RSuperellipse.fromRectAndRadius(
357+
Offset.zero & const Size.square(50),
358+
const Radius.circular(5),
359+
);
360+
final Paint paint = Paint()..color = Colors.blue;
361+
362+
Future<void> pumpPainter(WidgetTester tester) async {
363+
await tester.pumpWidget(
364+
Center(
365+
child: CustomPaint(
366+
painter: _RSuperellipsePainter(rsuperellipse: rsuperellipse, paint: paint),
367+
size: rsuperellipse.outerRect.size,
368+
),
369+
),
370+
);
371+
}
372+
373+
testWidgets('matches when rsuperellipse is correct', (WidgetTester tester) async {
374+
await pumpPainter(tester);
375+
expect(
376+
tester.renderObject(find.byType(CustomPaint)),
377+
paints..rsuperellipse(rsuperellipse: rsuperellipse),
378+
);
379+
});
380+
381+
testWidgets('does not match when rsuperellipse is incorrect', (WidgetTester tester) async {
382+
await pumpPainter(tester);
383+
384+
expect(
385+
() => expect(
386+
tester.renderObject(find.byType(CustomPaint)),
387+
paints..rsuperellipse(rsuperellipse: rsuperellipse.deflate(10)),
388+
),
389+
throwsA(
390+
isA<TestFailure>().having(
391+
(TestFailure failure) => failure.message,
392+
'message',
393+
contains(
394+
'It called drawRSuperellipse with a rounded superellipse, '
395+
'RSuperellipse.fromLTRBR(0.0, 0.0, 50.0, 50.0, 5.0), which was '
396+
'not exactly the expected rounded superellipse '
397+
'(RSuperellipse.fromLTRBR(10.0, 10.0, 40.0, 40.0, 0.0))',
398+
),
399+
),
400+
),
401+
);
402+
});
403+
});
354404
}
355405

356406
class _ArcPainter extends CustomPainter {
@@ -379,3 +429,21 @@ class _ArcPainter extends CustomPainter {
379429
return true;
380430
}
381431
}
432+
433+
class _RSuperellipsePainter extends CustomPainter {
434+
const _RSuperellipsePainter({required this.rsuperellipse, required Paint paint}) : _paint = paint;
435+
436+
final RSuperellipse rsuperellipse;
437+
438+
final Paint _paint;
439+
440+
@override
441+
void paint(Canvas canvas, Size size) {
442+
canvas.drawRSuperellipse(rsuperellipse, _paint);
443+
}
444+
445+
@override
446+
bool shouldRepaint(MyPainter oldDelegate) {
447+
return true;
448+
}
449+
}

0 commit comments

Comments
 (0)