@@ -11,74 +11,72 @@ import 'package:flutter/rendering.dart';
1111import 'package:flutter/services.dart' ;
1212import 'package:flutter_test/flutter_test.dart' ;
1313
14- void main () {
15- testWidgets ('RenderParagraph relayout upon system fonts changes' , (WidgetTester tester) async {
16- await tester.pumpWidget (
17- const MaterialApp (
18- home: Text ('text widget' ),
19- ),
20- );
21- final RenderObject renderObject = tester.renderObject (find.text ('text widget' ));
14+ Future <void > verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (WidgetTester tester, RenderObject renderObject) async {
15+ assert (! renderObject.debugNeedsLayout);
2216
23- const Map <String , dynamic > data = < String , dynamic > {
24- 'type' : 'fontsChange' ,
25- };
26- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
27- 'flutter/system' ,
28- SystemChannels .system.codec.encodeMessage (data),
29- (ByteData ? data) { },
30- );
17+ const Map <String , dynamic > data = < String , dynamic > {
18+ 'type' : 'fontsChange' ,
19+ };
20+ await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
21+ 'flutter/system' ,
22+ SystemChannels .system.codec.encodeMessage (data),
23+ (ByteData ? data) { },
24+ );
3125
32- final Completer <bool > animation = Completer <bool >();
33- tester.binding.scheduleFrameCallback ((Duration timeStamp) {
34- animation.complete (renderObject.debugNeedsLayout);
35- });
36- expect (renderObject.debugNeedsLayout, isFalse);
37- await tester.pump ();
38- expect (await animation.future, isTrue);
26+ final Completer <bool > animation = Completer <bool >();
27+ tester.binding.scheduleFrameCallback ((Duration timeStamp) {
28+ animation.complete (renderObject.debugNeedsLayout);
3929 });
4030
41- testWidgets ('Safe to query RenderParagraph for text layout after system fonts changes' , (WidgetTester tester) async {
31+ // The fonts change does not mark the render object as needing layout
32+ // immediately.
33+ expect (renderObject.debugNeedsLayout, isFalse);
34+ await tester.pump ();
35+ expect (await animation.future, isTrue);
36+ }
37+
38+ void main () {
39+ testWidgets ('RenderParagraph relayout upon system fonts changes' , (WidgetTester tester) async {
4240 await tester.pumpWidget (
4341 const MaterialApp (
4442 home: Text ('text widget' ),
4543 ),
4644 );
47- const Map <String , dynamic > data = < String , dynamic > {
48- 'type' : 'fontsChange' ,
49- };
50- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
51- 'flutter/system' ,
52- SystemChannels .system.codec.encodeMessage (data),
53- (ByteData ? data) { },
54- );
55- final RenderParagraph paragraph = tester.renderObject <RenderParagraph >(find.text ('text widget' ));
56- Object ? exception;
57- try {
58- paragraph.getPositionForOffset (Offset .zero);
59- paragraph.hitTest (BoxHitTestResult (), position: Offset .zero);
60- } catch (e) {
61- exception = e;
62- }
63- expect (exception, isNull);
45+ final RenderObject renderObject = tester.renderObject (find.text ('text widget' ));
46+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, renderObject);
6447 });
6548
49+ testWidgets (
50+ 'Safe to query a RelayoutWhenSystemFontsChangeMixin for text layout after system fonts changes' ,
51+ (WidgetTester tester) async {
52+ final _RenderCustomRelayoutWhenSystemFontsChange child = _RenderCustomRelayoutWhenSystemFontsChange ();
53+ await tester.pumpWidget (
54+ Directionality (
55+ textDirection: TextDirection .ltr,
56+ child: WidgetToRenderBoxAdapter (renderBox: child),
57+ ),
58+ );
59+ const Map <String , dynamic > data = < String , dynamic > {
60+ 'type' : 'fontsChange' ,
61+ };
62+ await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
63+ 'flutter/system' ,
64+ SystemChannels .system.codec.encodeMessage (data),
65+ (ByteData ? data) { },
66+ );
67+ expect (child.hasValidTextLayout, isTrue);
68+ },
69+ );
70+
6671 testWidgets ('RenderEditable relayout upon system fonts changes' , (WidgetTester tester) async {
6772 await tester.pumpWidget (
6873 const MaterialApp (
6974 home: SelectableText ('text widget' ),
7075 ),
7176 );
72- const Map <String , dynamic > data = < String , dynamic > {
73- 'type' : 'fontsChange' ,
74- };
75- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
76- 'flutter/system' ,
77- SystemChannels .system.codec.encodeMessage (data),
78- (ByteData ? data) { },
79- );
77+
8078 final EditableTextState state = tester.state (find.byType (EditableText ));
81- expect ( state.renderEditable.debugNeedsLayout, isTrue );
79+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, state.renderEditable);
8280 });
8381
8482 testWidgets ('Banner repaint upon system fonts changes' , (WidgetTester tester) async {
@@ -210,11 +208,8 @@ void main() {
210208 SystemChannels .system.codec.encodeMessage (data),
211209 (ByteData ? data) { },
212210 );
213- final RenderObject renderObject = tester.renderObject (find.byType (RangeSlider ));
214-
215- late bool sliderBoxNeedsLayout;
216- renderObject.visitChildren ((RenderObject child) {sliderBoxNeedsLayout = child.debugNeedsLayout;});
217- expect (sliderBoxNeedsLayout, isTrue);
211+ final RenderObject renderObject = tester.renderObject (find.byWidgetPredicate ((Widget widget) => widget.runtimeType.toString () == '_RangeSliderRenderObjectWidget' ));
212+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, renderObject);
218213 });
219214
220215 testWidgets ('Slider relayout upon system fonts changes' , (WidgetTester tester) async {
@@ -228,17 +223,9 @@ void main() {
228223 ),
229224 ),
230225 );
231- const Map <String , dynamic > data = < String , dynamic > {
232- 'type' : 'fontsChange' ,
233- };
234- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
235- 'flutter/system' ,
236- SystemChannels .system.codec.encodeMessage (data),
237- (ByteData ? data) { },
238- );
239226 // _RenderSlider is the last render object in the tree.
240227 final RenderObject renderObject = tester.allRenderObjects.last;
241- expect (renderObject.debugNeedsLayout, isTrue );
228+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, renderObject );
242229 });
243230
244231 testWidgets ('TimePicker relayout upon system fonts changes' , (WidgetTester tester) async {
@@ -289,3 +276,19 @@ void main() {
289276 expect (renderObject.debugNeedsPaint, isTrue);
290277 });
291278}
279+
280+ class _RenderCustomRelayoutWhenSystemFontsChange extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
281+ bool hasValidTextLayout = false ;
282+
283+ @override
284+ void systemFontsDidChange () {
285+ super .systemFontsDidChange ();
286+ hasValidTextLayout = false ;
287+ }
288+
289+ @override
290+ void performLayout () {
291+ size = constraints.biggest;
292+ hasValidTextLayout = true ;
293+ }
294+ }
0 commit comments