1// Copyright 2017 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'package:flutter/material.dart'; 6import 'package:flutter/widgets.dart'; 7import 'package:flutter/rendering.dart'; 8import 'package:flutter_test/flutter_test.dart'; 9 10import 'semantics_tester.dart'; 11 12void main() { 13 testWidgets('can cease to be semantics boundary after markNeedsSemanticsUpdate() has already been called once', (WidgetTester tester) async { 14 final SemanticsTester semantics = SemanticsTester(tester); 15 16 await tester.pumpWidget( 17 buildTestWidgets( 18 excludeSemantics: false, 19 label: 'label', 20 isSemanticsBoundary: true, 21 ), 22 ); 23 24 // The following should not trigger an assert. 25 await tester.pumpWidget( 26 buildTestWidgets( 27 excludeSemantics: true, 28 label: 'label CHANGED', 29 isSemanticsBoundary: false, 30 ), 31 ); 32 33 semantics.dispose(); 34 }); 35} 36 37Widget buildTestWidgets({ bool excludeSemantics, String label, bool isSemanticsBoundary }) { 38 return Directionality( 39 textDirection: TextDirection.ltr, 40 child: Semantics( 41 label: 'container', 42 container: true, 43 child: ExcludeSemantics( 44 excluding: excludeSemantics, 45 child: TestWidget( 46 label: label, 47 isSemanticBoundary: isSemanticsBoundary, 48 child: Column( 49 children: <Widget>[ 50 Semantics( 51 label: 'child1', 52 ), 53 Semantics( 54 label: 'child2', 55 ), 56 ], 57 ), 58 ), 59 ), 60 ), 61 ); 62} 63 64class TestWidget extends SingleChildRenderObjectWidget { 65 const TestWidget({ 66 Key key, 67 Widget child, 68 this.label, 69 this.isSemanticBoundary, 70 }) : super(key: key, child: child); 71 72 final String label; 73 final bool isSemanticBoundary; 74 75 @override 76 RenderTest createRenderObject(BuildContext context) { 77 return RenderTest() 78 ..label = label 79 ..isSemanticBoundary = isSemanticBoundary; 80 } 81 82 @override 83 void updateRenderObject(BuildContext context, RenderTest renderObject) { 84 renderObject 85 ..label = label 86 ..isSemanticBoundary = isSemanticBoundary; 87 } 88} 89 90class RenderTest extends RenderProxyBox { 91 92 @override 93 void describeSemanticsConfiguration(SemanticsConfiguration config) { 94 super.describeSemanticsConfiguration(config); 95 96 if (!_isSemanticBoundary) 97 return; 98 99 config 100 ..isSemanticBoundary = _isSemanticBoundary 101 ..label = _label 102 ..textDirection = TextDirection.ltr; 103 104 } 105 106 String _label = '<>'; 107 set label(String value) { 108 if (value == _label) 109 return; 110 _label = value; 111 markNeedsSemanticsUpdate(); 112 } 113 114 115 bool _isSemanticBoundary = false; 116 set isSemanticBoundary(bool value) { 117 if (_isSemanticBoundary == value) 118 return; 119 _isSemanticBoundary = value; 120 markNeedsSemanticsUpdate(); 121 } 122} 123