• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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